vantiv.io 1.0.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.
- package/LICENSE +21 -0
- package/README.md +864 -0
- package/index.js +13 -0
- package/package.json +28 -0
- package/src/classes/Actions/Awaiter.js +202 -0
- package/src/classes/Actions/Channel.js +73 -0
- package/src/classes/Actions/Direct.js +263 -0
- package/src/classes/Actions/Inventory.js +156 -0
- package/src/classes/Actions/Music.js +278 -0
- package/src/classes/Actions/Player.js +377 -0
- package/src/classes/Actions/Public.js +66 -0
- package/src/classes/Actions/Room.js +333 -0
- package/src/classes/Actions/Utils.js +29 -0
- package/src/classes/Actions/lib/AudioStreaming.js +447 -0
- package/src/classes/Caches/MovementCache.js +357 -0
- package/src/classes/Handlers/AxiosErrorHandler.js +68 -0
- package/src/classes/Handlers/ErrorHandler.js +65 -0
- package/src/classes/Handlers/EventHandlers.js +259 -0
- package/src/classes/Handlers/WebSocketHandlers.js +54 -0
- package/src/classes/Managers/ChannelManager.js +303 -0
- package/src/classes/Managers/DanceFloorManagers.js +509 -0
- package/src/classes/Managers/Helpers/CleanupManager.js +130 -0
- package/src/classes/Managers/Helpers/LoggerManager.js +171 -0
- package/src/classes/Managers/Helpers/MetricsManager.js +83 -0
- package/src/classes/Managers/Networking/ConnectionManager.js +259 -0
- package/src/classes/Managers/Networking/CooldownManager.js +516 -0
- package/src/classes/Managers/Networking/EventsManager.js +64 -0
- package/src/classes/Managers/Networking/KeepAliveManager.js +109 -0
- package/src/classes/Managers/Networking/MessageHandler.js +110 -0
- package/src/classes/Managers/Networking/Request.js +329 -0
- package/src/classes/Managers/PermissionManager.js +288 -0
- package/src/classes/WebApi/Category/Grab.js +98 -0
- package/src/classes/WebApi/Category/Item.js +347 -0
- package/src/classes/WebApi/Category/Post.js +154 -0
- package/src/classes/WebApi/Category/Room.js +137 -0
- package/src/classes/WebApi/Category/User.js +88 -0
- package/src/classes/WebApi/webapi.js +52 -0
- package/src/constants/TypesConstants.js +89 -0
- package/src/constants/WebSocketConstants.js +80 -0
- package/src/core/Highrise.js +123 -0
- package/src/core/HighriseWebsocket.js +228 -0
- package/src/utils/ConvertSvgToPng.js +51 -0
- package/src/utils/ModelPool.js +160 -0
- package/src/utils/Models.js +128 -0
- package/src/utils/versionCheck.js +27 -0
- package/src/validators/ConfigValidator.js +205 -0
- package/src/validators/ConnectionValidator.js +65 -0
- package/typings/index.d.ts +3820 -0
|
@@ -0,0 +1,3820 @@
|
|
|
1
|
+
/// <reference lib="dom" />
|
|
2
|
+
|
|
3
|
+
type Facing = "FrontRight" | "FrontLeft" | "BackRight" | "BackLeft"
|
|
4
|
+
type Reactions = 'clap' | 'heart' | 'thumbs' | 'wave' | 'wink'
|
|
5
|
+
type PaymentMethods = "bot_wallet_only" | "bot_wallet_priority" | "user_wallet_only"
|
|
6
|
+
type EventType =
|
|
7
|
+
| 'SessionMetadata'
|
|
8
|
+
| 'ChatEvent'
|
|
9
|
+
| 'WhisperEvent'
|
|
10
|
+
| 'UserMovedEvent'
|
|
11
|
+
| 'UserJoinedEvent'
|
|
12
|
+
| 'UserLeftEvent'
|
|
13
|
+
| 'MessageEvent'
|
|
14
|
+
| 'TipReactionEvent'
|
|
15
|
+
| 'RoomModeratedEvent'
|
|
16
|
+
| 'ChannelEvent'
|
|
17
|
+
|
|
18
|
+
type Goldbars = 1 | 5 | 10 | 50 | 100 | 500 | 1000 | 5000 | 10000
|
|
19
|
+
type ItemCategory =
|
|
20
|
+
| "bag"
|
|
21
|
+
| "blush"
|
|
22
|
+
| "body"
|
|
23
|
+
| "dress"
|
|
24
|
+
| "earrings"
|
|
25
|
+
| "emote"
|
|
26
|
+
| "eye"
|
|
27
|
+
| "eyebrow"
|
|
28
|
+
| "face_hair"
|
|
29
|
+
| "fishing_rod"
|
|
30
|
+
| "freckle"
|
|
31
|
+
| "glasses"
|
|
32
|
+
| "gloves"
|
|
33
|
+
| "hair_back"
|
|
34
|
+
| "hair_front"
|
|
35
|
+
| "handbag"
|
|
36
|
+
| "hat"
|
|
37
|
+
| "jacket"
|
|
38
|
+
| "lashes"
|
|
39
|
+
| "mole"
|
|
40
|
+
| "mouth"
|
|
41
|
+
| "necklace"
|
|
42
|
+
| "nose"
|
|
43
|
+
| "pants"
|
|
44
|
+
| "shirt"
|
|
45
|
+
| "shoes"
|
|
46
|
+
| "shorts"
|
|
47
|
+
| "skirt"
|
|
48
|
+
| "watch"
|
|
49
|
+
| "fullsuit"
|
|
50
|
+
| "sock"
|
|
51
|
+
| "tattoo"
|
|
52
|
+
| "rod"
|
|
53
|
+
| "aura";
|
|
54
|
+
|
|
55
|
+
type Rarity =
|
|
56
|
+
| "common"
|
|
57
|
+
| "uncommon"
|
|
58
|
+
| "rare"
|
|
59
|
+
| "epic"
|
|
60
|
+
| "legendary"
|
|
61
|
+
| "none_";
|
|
62
|
+
|
|
63
|
+
type ChannelListenerCallback = (message: ChannelMessage) => void | Promise<void>;
|
|
64
|
+
|
|
65
|
+
type RoomInviteOptions = {
|
|
66
|
+
room_id: string;
|
|
67
|
+
world_id?: never;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
type WorldInviteOptions = {
|
|
71
|
+
world_id: string;
|
|
72
|
+
room_id?: never;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
type CooldownMetadata = Record<string, any>;
|
|
76
|
+
|
|
77
|
+
type InviteOptions = RoomInviteOptions | WorldInviteOptions;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Chat event filter function
|
|
81
|
+
* @param user - The user who sent the message
|
|
82
|
+
* @param message - The message content
|
|
83
|
+
* @returns boolean indicating if the event matches the filter
|
|
84
|
+
*/
|
|
85
|
+
type ChatFilter = (user: User, message: string) => boolean;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Whisper event filter function
|
|
89
|
+
* @param user - The user who sent the whisper
|
|
90
|
+
* @param message - The whisper content
|
|
91
|
+
* @returns boolean indicating if the event matches the filter
|
|
92
|
+
*/
|
|
93
|
+
type WhisperFilter = (user: User, message: string) => boolean;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Direct message event filter function
|
|
97
|
+
* @param user - The user who sent the direct message
|
|
98
|
+
* @param message - The message content
|
|
99
|
+
* @param conversation - The conversation information
|
|
100
|
+
* @returns boolean indicating if the event matches the filter
|
|
101
|
+
*/
|
|
102
|
+
type DirectFilter = (user: User, message: string, conversation: Conversation) => boolean;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Tip event filter function
|
|
106
|
+
* @param sender - The user who sent the tip
|
|
107
|
+
* @param receiver - The user who received the tip
|
|
108
|
+
* @param currency - The tip currency information
|
|
109
|
+
* @returns boolean indicating if the event matches the filter
|
|
110
|
+
*/
|
|
111
|
+
type TipFilter = (sender: Sender, receiver: Receiver, currency: Currency) => boolean;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Movement event filter function
|
|
115
|
+
* @param user - The user who moved
|
|
116
|
+
* @param position - The new position of the user
|
|
117
|
+
* @param anchor - The anchor position if user is sitting, null if standing
|
|
118
|
+
* @returns boolean indicating if the movement matches the filter
|
|
119
|
+
*/
|
|
120
|
+
type MovementFilter = (user: User, position: Position, anchor: AnchorPosition | null) => boolean;
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
interface User {
|
|
124
|
+
id: string;
|
|
125
|
+
username: string;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
interface Sender extends User { }
|
|
129
|
+
interface Receiver extends User { }
|
|
130
|
+
|
|
131
|
+
interface Position {
|
|
132
|
+
x: number;
|
|
133
|
+
y: number;
|
|
134
|
+
z: number;
|
|
135
|
+
facing: string;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
interface AnchorPosition {
|
|
139
|
+
entity_id: string;
|
|
140
|
+
anchor_ix: number;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
interface WalletResponse {
|
|
144
|
+
gold: number;
|
|
145
|
+
boost_tokens: number;
|
|
146
|
+
voice_tokens: number;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
interface PermissionStats {
|
|
150
|
+
webapiSyncs: number;
|
|
151
|
+
fileSaves: number;
|
|
152
|
+
lastSync: number;
|
|
153
|
+
lastSave: number;
|
|
154
|
+
roles: number;
|
|
155
|
+
users: number;
|
|
156
|
+
webapiModerators: number;
|
|
157
|
+
webapiDesigners: number;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
interface RoleObjectStructure {
|
|
161
|
+
[roleName: string]: string[]
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
interface GetRoomPrivilegeResponse {
|
|
165
|
+
moderator: boolean;
|
|
166
|
+
designer: boolean;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
interface GetConversationsResponse {
|
|
170
|
+
id: string;
|
|
171
|
+
did_join: boolean;
|
|
172
|
+
unread_count: number;
|
|
173
|
+
last_message: string;
|
|
174
|
+
muted: boolean;
|
|
175
|
+
member_ids: string[];
|
|
176
|
+
name: string | null;
|
|
177
|
+
owner_id: string | null
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
interface Currency {
|
|
181
|
+
type: string;
|
|
182
|
+
amount: number
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
interface GetMessagesResponse {
|
|
186
|
+
message_id: string,
|
|
187
|
+
conversation_id: string,
|
|
188
|
+
createdAt: Date,
|
|
189
|
+
content: string,
|
|
190
|
+
sender_id: string,
|
|
191
|
+
category: string
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
interface ReadyEventMetadata {
|
|
195
|
+
connection_id: string
|
|
196
|
+
rate_limits: {
|
|
197
|
+
client: [number, number],
|
|
198
|
+
socials: [number, number]
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
interface ModerationAction {
|
|
203
|
+
type: string;
|
|
204
|
+
duration: number
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
interface BotInformation {
|
|
208
|
+
user: User;
|
|
209
|
+
room: {
|
|
210
|
+
id: string;
|
|
211
|
+
name: string;
|
|
212
|
+
owner_id: string;
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
interface ReadyEvent {
|
|
217
|
+
bot_id: string;
|
|
218
|
+
room: {
|
|
219
|
+
owner_id: string;
|
|
220
|
+
room_name: string;
|
|
221
|
+
}
|
|
222
|
+
metadata: ReadyEventMetadata
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
interface MetricData {
|
|
226
|
+
uptime: string;
|
|
227
|
+
connected: boolean;
|
|
228
|
+
room: string;
|
|
229
|
+
messages: number;
|
|
230
|
+
events: number;
|
|
231
|
+
errors: number;
|
|
232
|
+
cache: {
|
|
233
|
+
users: number;
|
|
234
|
+
memory: string;
|
|
235
|
+
active: number;
|
|
236
|
+
changes: number;
|
|
237
|
+
};
|
|
238
|
+
pendingReq: {
|
|
239
|
+
fireForget: number;
|
|
240
|
+
reqRes: number;
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
interface LoggerOptions {
|
|
245
|
+
showTimestamp?: boolean;
|
|
246
|
+
showMethodName?: boolean;
|
|
247
|
+
colors?: boolean;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
interface Conversation {
|
|
251
|
+
id: `1_on_1:${string}:${string}`
|
|
252
|
+
is_new_conversation: boolean;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
interface Outfit {
|
|
256
|
+
type: string;
|
|
257
|
+
amount: number;
|
|
258
|
+
id: string;
|
|
259
|
+
account_bound: boolean;
|
|
260
|
+
active_palette: number | null;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
interface GetInventoryResponse extends Outfit { }
|
|
264
|
+
|
|
265
|
+
interface GetUserOutfitResponse extends Outfit { }
|
|
266
|
+
|
|
267
|
+
interface getUserAvatarResponse {
|
|
268
|
+
success: boolean,
|
|
269
|
+
width: number,
|
|
270
|
+
height: number,
|
|
271
|
+
size: number
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
interface ValidVoiceCheck {
|
|
275
|
+
secondsLeft: number,
|
|
276
|
+
autoSpeakersId: string[],
|
|
277
|
+
users: object
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
interface InvalidVoiceCheck {
|
|
281
|
+
message: string
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
interface CooldownInfo {
|
|
285
|
+
expiresAt: number;
|
|
286
|
+
duration: number;
|
|
287
|
+
metadata: CooldownMetadata;
|
|
288
|
+
remainingMs: number;
|
|
289
|
+
remainingSeconds: number;
|
|
290
|
+
progress: number;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
interface GlobalCooldownInfo {
|
|
294
|
+
expiresAt: number;
|
|
295
|
+
duration: number;
|
|
296
|
+
setAt: number;
|
|
297
|
+
remainingMs: number;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
interface GroupConfig {
|
|
301
|
+
defaultDuration: number;
|
|
302
|
+
maxConcurrent: number;
|
|
303
|
+
perUserLimit: number | null;
|
|
304
|
+
[key: string]: any;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
interface CheckGroupResult {
|
|
308
|
+
allowed: boolean;
|
|
309
|
+
reason?: 'max_concurrent' | 'user_limit' | 'user_cooldown';
|
|
310
|
+
duration?: number;
|
|
311
|
+
remainingMs?: number;
|
|
312
|
+
remainingSeconds?: number;
|
|
313
|
+
message?: string;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
interface StartGroupResult {
|
|
317
|
+
success: boolean;
|
|
318
|
+
actionId?: string;
|
|
319
|
+
startedAt?: number;
|
|
320
|
+
duration?: number;
|
|
321
|
+
allowed?: boolean;
|
|
322
|
+
reason?: 'max_concurrent' | 'user_limit' | 'user_cooldown';
|
|
323
|
+
message?: string;
|
|
324
|
+
remainingMs?: number;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
interface AttemptResult {
|
|
328
|
+
success: boolean;
|
|
329
|
+
onCooldown: boolean;
|
|
330
|
+
executed?: boolean;
|
|
331
|
+
result?: any;
|
|
332
|
+
error?: Error;
|
|
333
|
+
cooldownSet?: boolean;
|
|
334
|
+
durationMs?: number;
|
|
335
|
+
remainingMs?: number;
|
|
336
|
+
remainingSeconds?: number;
|
|
337
|
+
data?: CooldownMetadata;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
interface UserCooldown {
|
|
341
|
+
key: string;
|
|
342
|
+
remainingMs: number;
|
|
343
|
+
expiresAt: number;
|
|
344
|
+
metadata: CooldownMetadata;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
interface CooldownMemoryUsage {
|
|
348
|
+
cooldowns: string;
|
|
349
|
+
globals: string;
|
|
350
|
+
groups: string;
|
|
351
|
+
total: string;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
interface GroupStats {
|
|
355
|
+
active: number;
|
|
356
|
+
totalUsage: number;
|
|
357
|
+
config: GroupConfig;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
interface CooldownManagerStats {
|
|
361
|
+
totalChecks: number;
|
|
362
|
+
blockedActions: number;
|
|
363
|
+
successfulActions: number;
|
|
364
|
+
averageCooldownTime: number;
|
|
365
|
+
activeCooldowns: number;
|
|
366
|
+
activeGlobals: number;
|
|
367
|
+
groups: Record<string, GroupStats>;
|
|
368
|
+
memoryUsage: CooldownMemoryUsage;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
interface EventMap {
|
|
372
|
+
UserLeft: [user: User]
|
|
373
|
+
Ready: [session: ReadyEvent]
|
|
374
|
+
Chat: [user: User, message: string]
|
|
375
|
+
Whisper: [user: User, message: string]
|
|
376
|
+
UserJoined: [user: User, position: Position]
|
|
377
|
+
Voice: [users: VoiceUser[], secondsLeft: number, ended: boolean]
|
|
378
|
+
Channel: [senderId: string, message: string, tags: string[]]
|
|
379
|
+
Tip: [sender: Sender, receiver: Receiver, currency: Currency]
|
|
380
|
+
Direct: [user: User, message: string, conversation: Conversation]
|
|
381
|
+
Moderation: [moderator: User, target: User, action: ModerationAction]
|
|
382
|
+
Movement: [user: User, position: Position | null, anchor: AnchorPosition | null]
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
interface CachedUser {
|
|
388
|
+
position: Position;
|
|
389
|
+
anchor: AnchorPosition | null;
|
|
390
|
+
lastSeen: number;
|
|
391
|
+
username: string;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
interface CachedPosition extends Position {
|
|
395
|
+
lastUpdated: number;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
interface SpatialUser {
|
|
399
|
+
user: User;
|
|
400
|
+
position: CachedPosition;
|
|
401
|
+
anchor: {
|
|
402
|
+
entity_id: string;
|
|
403
|
+
anchor_ix: number;
|
|
404
|
+
} | null;
|
|
405
|
+
lastSeen: number;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
interface VoiceUser {
|
|
409
|
+
user: User,
|
|
410
|
+
/**
|
|
411
|
+
* Either "muted" or "voice"
|
|
412
|
+
*/
|
|
413
|
+
status: string
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
interface SpatialUserWithDistance extends SpatialUser {
|
|
417
|
+
distance: number;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
interface RectangleCorners {
|
|
421
|
+
c1: { x: number; z: number };
|
|
422
|
+
c2: { x: number; z: number };
|
|
423
|
+
c3: { x: number; z: number };
|
|
424
|
+
c4: { x: number; z: number };
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
interface WebApiUser {
|
|
428
|
+
id: string;
|
|
429
|
+
username: string;
|
|
430
|
+
bio: string;
|
|
431
|
+
joinedAt: string;
|
|
432
|
+
lastOnline: string;
|
|
433
|
+
followers: number;
|
|
434
|
+
following: number;
|
|
435
|
+
friends: number;
|
|
436
|
+
currentRoom: string;
|
|
437
|
+
country: string;
|
|
438
|
+
crew: string;
|
|
439
|
+
voiceEnabled: boolean;
|
|
440
|
+
discordConnected: boolean;
|
|
441
|
+
avatar: string;
|
|
442
|
+
icon: string;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
interface BasicRoom {
|
|
446
|
+
id: string;
|
|
447
|
+
name: string;
|
|
448
|
+
description: string | null;
|
|
449
|
+
category: string;
|
|
450
|
+
createdAt: string | null;
|
|
451
|
+
accessPolicy: string;
|
|
452
|
+
ownerId: string;
|
|
453
|
+
languages: string[];
|
|
454
|
+
isHomeRoom: boolean;
|
|
455
|
+
designerIds: string[];
|
|
456
|
+
moderatorIds: string[];
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
interface DetailedRoom extends BasicRoom {
|
|
460
|
+
connectedUsers: number;
|
|
461
|
+
thumbnail: string;
|
|
462
|
+
banner: string;
|
|
463
|
+
crewId: string;
|
|
464
|
+
bots: any[];
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
interface RoomsListResponse {
|
|
468
|
+
rooms: BasicRoom[];
|
|
469
|
+
pagination: {
|
|
470
|
+
total: number;
|
|
471
|
+
firstId: string;
|
|
472
|
+
lastId: string;
|
|
473
|
+
hasMore: boolean;
|
|
474
|
+
};
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
interface PostBody {
|
|
478
|
+
text: string;
|
|
479
|
+
inventory: PostInventory | null;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
interface PostInventory {
|
|
483
|
+
items: PostItem[];
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
interface PostItem {
|
|
487
|
+
itemId: string;
|
|
488
|
+
activePalette: number | null;
|
|
489
|
+
accountBound: boolean;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
interface PostComment {
|
|
493
|
+
id: string;
|
|
494
|
+
content: string;
|
|
495
|
+
postId: string;
|
|
496
|
+
authorId: string;
|
|
497
|
+
authorName: string;
|
|
498
|
+
likes: number;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
interface PostListItem {
|
|
502
|
+
id: string;
|
|
503
|
+
authorId: string | null;
|
|
504
|
+
createdAt: string | null;
|
|
505
|
+
type: string | null;
|
|
506
|
+
visibility: string;
|
|
507
|
+
stats: {
|
|
508
|
+
comments: number;
|
|
509
|
+
likes: number;
|
|
510
|
+
reposts: number;
|
|
511
|
+
};
|
|
512
|
+
content: {
|
|
513
|
+
text: string;
|
|
514
|
+
hasBody: boolean;
|
|
515
|
+
caption: string | null;
|
|
516
|
+
};
|
|
517
|
+
fileKey: string | null;
|
|
518
|
+
featuredUserIds: string[];
|
|
519
|
+
inventory: PostInventory | null;
|
|
520
|
+
body: PostBody | null;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
interface Post extends PostListItem {
|
|
524
|
+
comments: PostComment[];
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
interface PostsListResponse {
|
|
528
|
+
posts: PostListItem[];
|
|
529
|
+
pagination: {
|
|
530
|
+
total: number;
|
|
531
|
+
firstId: string;
|
|
532
|
+
lastId: string;
|
|
533
|
+
hasMore: boolean;
|
|
534
|
+
};
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
interface Affiliation {
|
|
538
|
+
id: string;
|
|
539
|
+
title: string;
|
|
540
|
+
type: string;
|
|
541
|
+
eventType: string | null;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
interface OutfitItem {
|
|
545
|
+
itemId: string;
|
|
546
|
+
name: string;
|
|
547
|
+
rarity: string;
|
|
548
|
+
activePalette: number;
|
|
549
|
+
parts: number;
|
|
550
|
+
colors: OutfitItemColors | null;
|
|
551
|
+
linkedColors: string;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
interface Seller {
|
|
555
|
+
userId: string;
|
|
556
|
+
username: string;
|
|
557
|
+
outfit: OutfitItem[];
|
|
558
|
+
lastConnectedAt: any | null;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
|
|
562
|
+
interface StorefrontListings {
|
|
563
|
+
sellers: Seller[];
|
|
564
|
+
pages: number;
|
|
565
|
+
total: number;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
interface OutfitItemColors {
|
|
569
|
+
linkedColors: string;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
interface SkinPart {
|
|
573
|
+
bone: string;
|
|
574
|
+
slot: string;
|
|
575
|
+
imageFile: string;
|
|
576
|
+
attachmentName: string | null;
|
|
577
|
+
hasRemoteRenderLayer: boolean | null;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
interface Item {
|
|
581
|
+
id: string;
|
|
582
|
+
name: string;
|
|
583
|
+
category: any | null;
|
|
584
|
+
colorLinkedCategories: any | null;
|
|
585
|
+
colorPalettes: any | null;
|
|
586
|
+
createdAt: any | null;
|
|
587
|
+
description: string | null;
|
|
588
|
+
pricing: {
|
|
589
|
+
gems: number | null;
|
|
590
|
+
pops: number | null;
|
|
591
|
+
};
|
|
592
|
+
properties: {
|
|
593
|
+
isPurchasable: boolean;
|
|
594
|
+
isTradable: boolean;
|
|
595
|
+
};
|
|
596
|
+
images: {
|
|
597
|
+
main: string | null;
|
|
598
|
+
icon: string | null;
|
|
599
|
+
};
|
|
600
|
+
links: {
|
|
601
|
+
linkIds: string[];
|
|
602
|
+
inspiredBy: any | null;
|
|
603
|
+
};
|
|
604
|
+
skinParts: {
|
|
605
|
+
front: SkinPart[];
|
|
606
|
+
back: SkinPart[];
|
|
607
|
+
};
|
|
608
|
+
metadata: {
|
|
609
|
+
dependentColors: any | null;
|
|
610
|
+
releaseDate: any | null;
|
|
611
|
+
keywords: any | null;
|
|
612
|
+
};
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
interface ItemsSearchResponse {
|
|
616
|
+
items: Item[];
|
|
617
|
+
pagination: {
|
|
618
|
+
total: number;
|
|
619
|
+
hasMore: boolean;
|
|
620
|
+
skip: number;
|
|
621
|
+
};
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
interface ItemDetail extends Item {
|
|
625
|
+
acquisition: {
|
|
626
|
+
cost: number | null;
|
|
627
|
+
amount: number | null;
|
|
628
|
+
currency: string | null;
|
|
629
|
+
};
|
|
630
|
+
metadata: {
|
|
631
|
+
dependentColors: any[];
|
|
632
|
+
releaseDate: any | null;
|
|
633
|
+
keywords: any | null;
|
|
634
|
+
};
|
|
635
|
+
relatedItems: {
|
|
636
|
+
items: Array<{
|
|
637
|
+
id: string;
|
|
638
|
+
name: string;
|
|
639
|
+
}>;
|
|
640
|
+
} | null;
|
|
641
|
+
affiliations: Affiliation[];
|
|
642
|
+
storefrontListings: StorefrontListings | null;
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
interface ItemsListResponse {
|
|
646
|
+
items: Item[];
|
|
647
|
+
pagination: {
|
|
648
|
+
total: number;
|
|
649
|
+
firstId: string;
|
|
650
|
+
lastId: string;
|
|
651
|
+
hasMore: boolean;
|
|
652
|
+
};
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
interface Grab {
|
|
656
|
+
id: string;
|
|
657
|
+
title: string;
|
|
658
|
+
description: string;
|
|
659
|
+
bannerImgUrl: string;
|
|
660
|
+
startsAt: any | null;
|
|
661
|
+
expiresAt: any | null;
|
|
662
|
+
rewards: GrabReward[];
|
|
663
|
+
costs: GrabCost[];
|
|
664
|
+
kompuRewards: GrabReward[];
|
|
665
|
+
limitedTimeKompu: LimitedKompu | null;
|
|
666
|
+
progressReward: ProgressReward | null;
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
interface GrabReward {
|
|
670
|
+
amount: number;
|
|
671
|
+
rewardId: string;
|
|
672
|
+
itemId: string | null;
|
|
673
|
+
accountBound: boolean;
|
|
674
|
+
metadata: any | null;
|
|
675
|
+
nfiMetadata: any | null;
|
|
676
|
+
itemNumber: number;
|
|
677
|
+
stackId: string;
|
|
678
|
+
nfiTemplateMetadata: any | null;
|
|
679
|
+
totalAmount: number | null;
|
|
680
|
+
bannerItem: boolean;
|
|
681
|
+
primaryImgUrl: string | null;
|
|
682
|
+
secondaryImgUrl: string | null;
|
|
683
|
+
isTradable: boolean;
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
interface GrabCost {
|
|
687
|
+
amount: number;
|
|
688
|
+
rewardId: string;
|
|
689
|
+
itemId: string | null;
|
|
690
|
+
accountBound: boolean;
|
|
691
|
+
metadata: any | null;
|
|
692
|
+
nfiMetadata: any | null;
|
|
693
|
+
itemNumber: number;
|
|
694
|
+
stackId: string;
|
|
695
|
+
nfiTemplateMetadata: any | null;
|
|
696
|
+
totalAmount: number | null;
|
|
697
|
+
bannerItem: boolean;
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
interface LimitedKompu {
|
|
701
|
+
expiresAt: any | null;
|
|
702
|
+
rewards: GrabReward[];
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
interface ProgressReward {
|
|
706
|
+
rewardsAt: number;
|
|
707
|
+
rewards: GrabReward[];
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
interface ItemsSearchParams {
|
|
711
|
+
/**
|
|
712
|
+
* Maximum number of items to return (default: 20, max: 100, min: 1)
|
|
713
|
+
*/
|
|
714
|
+
limit?: number;
|
|
715
|
+
|
|
716
|
+
/**
|
|
717
|
+
* Number of items to skip (for pagination), default: 0
|
|
718
|
+
*/
|
|
719
|
+
skip?: number;
|
|
720
|
+
|
|
721
|
+
/**
|
|
722
|
+
* Search query for item names
|
|
723
|
+
* @example
|
|
724
|
+
* 'Fiery Creature Eyes'
|
|
725
|
+
*/
|
|
726
|
+
query?: string;
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
interface RoomsParams {
|
|
730
|
+
/**
|
|
731
|
+
* Maximum number of rooms to return (default: 20, max: 100, min: 1)
|
|
732
|
+
*/
|
|
733
|
+
limit?: number;
|
|
734
|
+
|
|
735
|
+
/**
|
|
736
|
+
* Sort order for the results
|
|
737
|
+
* - `asc`: Oldest rooms first
|
|
738
|
+
* - `desc`: Newest rooms first (default)
|
|
739
|
+
*/
|
|
740
|
+
sort_order?: 'asc' | 'desc';
|
|
741
|
+
|
|
742
|
+
/**
|
|
743
|
+
* Filter rooms by owner user ID
|
|
744
|
+
* @example '68a7dd5eecae68acca580f41'
|
|
745
|
+
*/
|
|
746
|
+
owner_id?: string;
|
|
747
|
+
|
|
748
|
+
/**
|
|
749
|
+
* Filter rooms by name (partial match)
|
|
750
|
+
*/
|
|
751
|
+
room_name?: string;
|
|
752
|
+
|
|
753
|
+
/**
|
|
754
|
+
* Pagination cursor - get rooms created after this room ID
|
|
755
|
+
* Used for forward pagination
|
|
756
|
+
* @example '692505a6bf18ebcc157260ec'
|
|
757
|
+
*/
|
|
758
|
+
starts_after?: string;
|
|
759
|
+
|
|
760
|
+
/**
|
|
761
|
+
* Pagination cursor - get rooms created before this room ID
|
|
762
|
+
* Used for backward pagination
|
|
763
|
+
* @example '68a7dd5eecae68acca580f41'
|
|
764
|
+
*/
|
|
765
|
+
ends_before?: string;
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
interface PostsParams {
|
|
769
|
+
/**
|
|
770
|
+
* Maximum number of posts to return (default: 20, max: 100, min: 1)
|
|
771
|
+
*/
|
|
772
|
+
limit?: number;
|
|
773
|
+
|
|
774
|
+
/**
|
|
775
|
+
* Sort order for the results
|
|
776
|
+
* - `asc`: Oldest posts first
|
|
777
|
+
* - `desc`: Newest posts first (default)
|
|
778
|
+
*/
|
|
779
|
+
sort_order?: 'asc' | 'desc';
|
|
780
|
+
|
|
781
|
+
/**
|
|
782
|
+
* Filter posts by author user ID
|
|
783
|
+
* @example '68a7dd5eecae68acca580f41'
|
|
784
|
+
*/
|
|
785
|
+
author_id?: string;
|
|
786
|
+
|
|
787
|
+
/**
|
|
788
|
+
* Pagination cursor - get posts created after this post ID
|
|
789
|
+
* Used for forward pagination
|
|
790
|
+
* @example 'post_123456'
|
|
791
|
+
*/
|
|
792
|
+
starts_after?: string;
|
|
793
|
+
|
|
794
|
+
/**
|
|
795
|
+
* Pagination cursor - get posts created before this post ID
|
|
796
|
+
* Used for backward pagination
|
|
797
|
+
* @example 'post_789012'
|
|
798
|
+
*/
|
|
799
|
+
ends_before?: string;
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
interface ItemsParams {
|
|
803
|
+
/**
|
|
804
|
+
* Maximum number of items to return (default: 20, max: 100, min: 1)
|
|
805
|
+
*/
|
|
806
|
+
limit?: number;
|
|
807
|
+
|
|
808
|
+
/**
|
|
809
|
+
* Sort order for the results
|
|
810
|
+
* - `asc`: Oldest items first
|
|
811
|
+
* - `desc`: Newest items first (default)
|
|
812
|
+
*/
|
|
813
|
+
sort_order?: 'asc' | 'desc';
|
|
814
|
+
|
|
815
|
+
/**
|
|
816
|
+
* Filter items by rarity
|
|
817
|
+
* @example Rarity.RARE
|
|
818
|
+
* @example Rarity.EPIC
|
|
819
|
+
*/
|
|
820
|
+
rarity?: Rarity;
|
|
821
|
+
|
|
822
|
+
/**
|
|
823
|
+
* Filter items by name (partial match)
|
|
824
|
+
* @example
|
|
825
|
+
* 'Fiery Creature Eyes'
|
|
826
|
+
*/
|
|
827
|
+
item_name?: string;
|
|
828
|
+
|
|
829
|
+
/**
|
|
830
|
+
* Filter items by category
|
|
831
|
+
* @example ItemCategory.SHIRT
|
|
832
|
+
* @example ItemCategory.HAT
|
|
833
|
+
*/
|
|
834
|
+
category?: ItemCategory;
|
|
835
|
+
|
|
836
|
+
/**
|
|
837
|
+
* Pagination cursor - get items created after this item ID
|
|
838
|
+
* Used for forward pagination
|
|
839
|
+
* @example 'item_123456'
|
|
840
|
+
*/
|
|
841
|
+
starts_after?: string;
|
|
842
|
+
|
|
843
|
+
/**
|
|
844
|
+
* Pagination cursor - get items created before this item ID
|
|
845
|
+
* Used for backward pagination
|
|
846
|
+
* @example 'item_789012'
|
|
847
|
+
*/
|
|
848
|
+
ends_before?: string;
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
interface DanceEmote {
|
|
852
|
+
id: string;
|
|
853
|
+
name: string;
|
|
854
|
+
duration: number;
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
interface DancingPlayer {
|
|
858
|
+
id: string;
|
|
859
|
+
username: string;
|
|
860
|
+
position: any;
|
|
861
|
+
timeoutId: NodeJS.Timeout
|
|
862
|
+
emoteIndex: number;
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
interface DanceFloorCorners {
|
|
866
|
+
x: number;
|
|
867
|
+
y: number;
|
|
868
|
+
z: number;
|
|
869
|
+
x1: number;
|
|
870
|
+
z1: number;
|
|
871
|
+
y1: number;
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
interface DanceFloorConfig {
|
|
875
|
+
id: string;
|
|
876
|
+
corners: DanceFloorCorners;
|
|
877
|
+
emotes: DanceEmote[];
|
|
878
|
+
players: DancingPlayer[];
|
|
879
|
+
filePath?: string;
|
|
880
|
+
hasWatcher?: boolean
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
/**
|
|
884
|
+
* Represents a hidden channel message
|
|
885
|
+
* Used for bot-to-bot communication within the same room
|
|
886
|
+
*/
|
|
887
|
+
interface ChannelMessage {
|
|
888
|
+
/**
|
|
889
|
+
* Unique identifier for the message (UUID v4)
|
|
890
|
+
* @example "123e4567-e89b-12d3-a456-426614174000"
|
|
891
|
+
*/
|
|
892
|
+
id: string;
|
|
893
|
+
|
|
894
|
+
/**
|
|
895
|
+
* The actual message content
|
|
896
|
+
* Can be any string data (JSON, plain text, etc.)
|
|
897
|
+
* @example "{\"username\":\"Player1\",\"action\":\"kicked\",\"reason\":\"spamming\"}"
|
|
898
|
+
* @example "Game started! Round 1"
|
|
899
|
+
*/
|
|
900
|
+
message: string;
|
|
901
|
+
|
|
902
|
+
/**
|
|
903
|
+
* Normalized tags for categorization and filtering
|
|
904
|
+
* Tags are sorted alphabetically and in lowercase
|
|
905
|
+
* @example ["game", "start", "room-123"]
|
|
906
|
+
* @example ["moderation", "kick", "chat"]
|
|
907
|
+
*/
|
|
908
|
+
tags: string[];
|
|
909
|
+
|
|
910
|
+
/**
|
|
911
|
+
* Unix timestamp in milliseconds when the message was stored locally
|
|
912
|
+
* @example 1703000000000
|
|
913
|
+
*/
|
|
914
|
+
timestamp: number;
|
|
915
|
+
|
|
916
|
+
/**
|
|
917
|
+
* ID of the bot/user who sent the message
|
|
918
|
+
* @example "68a7dd5eecae68acca580f41"
|
|
919
|
+
*/
|
|
920
|
+
senderId: string;
|
|
921
|
+
|
|
922
|
+
/**
|
|
923
|
+
* Whether this message was sent by the current bot instance
|
|
924
|
+
* - `true`: Message was sent by this bot
|
|
925
|
+
* - `false`: Message was received from another bot
|
|
926
|
+
*/
|
|
927
|
+
sent: boolean;
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
/**
|
|
931
|
+
* Filter criteria for querying channel messages
|
|
932
|
+
*/
|
|
933
|
+
interface ChannelFilter {
|
|
934
|
+
/**
|
|
935
|
+
* Tags to filter messages by
|
|
936
|
+
* All specified tags must be present in the message
|
|
937
|
+
* @example ["game", "start"] - Only messages with BOTH "game" AND "start" tags
|
|
938
|
+
* @example ["moderation"] - Only messages with "moderation" tag
|
|
939
|
+
*/
|
|
940
|
+
tags?: string | string[];
|
|
941
|
+
|
|
942
|
+
/**
|
|
943
|
+
* Start timestamp in milliseconds (inclusive)
|
|
944
|
+
* Only messages with timestamp >= since will be returned
|
|
945
|
+
* @default 0 (no lower bound)
|
|
946
|
+
* @example Date.now() - 3600000 // Last hour
|
|
947
|
+
*/
|
|
948
|
+
since?: number;
|
|
949
|
+
|
|
950
|
+
/**
|
|
951
|
+
* End timestamp in milliseconds (inclusive)
|
|
952
|
+
* Only messages with timestamp <= until will be returned
|
|
953
|
+
* @default Date.now() (current time)
|
|
954
|
+
* @example Date.now() - 60000 // Up to 1 minute ago
|
|
955
|
+
*/
|
|
956
|
+
until?: number;
|
|
957
|
+
|
|
958
|
+
/**
|
|
959
|
+
* Maximum number of messages to return
|
|
960
|
+
* @default 50
|
|
961
|
+
* @minimum 1
|
|
962
|
+
* @maximum 1000
|
|
963
|
+
* @example 10 - Return only 10 most recent messages
|
|
964
|
+
*/
|
|
965
|
+
limit?: number;
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
/**
|
|
969
|
+
* Statistics about the channel system
|
|
970
|
+
*/
|
|
971
|
+
interface ChannelStats {
|
|
972
|
+
/**
|
|
973
|
+
* Total number of messages currently stored in history
|
|
974
|
+
* Older messages are automatically removed (max 500)
|
|
975
|
+
* @example 127
|
|
976
|
+
*/
|
|
977
|
+
totalMessages: number;
|
|
978
|
+
|
|
979
|
+
/**
|
|
980
|
+
* Number of active listeners/subscriptions
|
|
981
|
+
* @example 3
|
|
982
|
+
*/
|
|
983
|
+
listeners: number;
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
declare class RoleManager {
|
|
987
|
+
/**
|
|
988
|
+
* Create a new custom role
|
|
989
|
+
* @param roleName - Name of the role (any string)
|
|
990
|
+
* @returns True if created, false if already exists
|
|
991
|
+
*/
|
|
992
|
+
createRole(roleName: string): boolean;
|
|
993
|
+
|
|
994
|
+
/**
|
|
995
|
+
* Add user to a role
|
|
996
|
+
* @param roleName - Role to add to
|
|
997
|
+
* @param userId - User ID to add
|
|
998
|
+
* @returns True if added, false if already in role
|
|
999
|
+
*/
|
|
1000
|
+
addToRole(roleName: string, userId: string): boolean;
|
|
1001
|
+
|
|
1002
|
+
/**
|
|
1003
|
+
* Remove user from a role
|
|
1004
|
+
* @param roleName - Role to remove from
|
|
1005
|
+
* @param userId - User ID to remove
|
|
1006
|
+
* @returns True if removed, false if not in role
|
|
1007
|
+
*/
|
|
1008
|
+
removeFromRole(roleName: string, userId: string): boolean;
|
|
1009
|
+
|
|
1010
|
+
/**
|
|
1011
|
+
* Check if user is in a role
|
|
1012
|
+
* @param roleName - Role to check
|
|
1013
|
+
* @param userId - User ID to check
|
|
1014
|
+
* @returns True if user has the role
|
|
1015
|
+
*/
|
|
1016
|
+
hasRole(roleName: string, userId: string): boolean;
|
|
1017
|
+
|
|
1018
|
+
/**
|
|
1019
|
+
* Check if user is in any of the given roles
|
|
1020
|
+
* @param roleNames - Array of roles to check
|
|
1021
|
+
* @param userId - User ID to check
|
|
1022
|
+
* @returns True if user has any of the roles
|
|
1023
|
+
*/
|
|
1024
|
+
hasAnyRole(roleNames: string[], userId: string): boolean;
|
|
1025
|
+
|
|
1026
|
+
/**
|
|
1027
|
+
* Get all roles a user is in
|
|
1028
|
+
* @param userId - User ID to check
|
|
1029
|
+
* @returns Array of role names
|
|
1030
|
+
*/
|
|
1031
|
+
getUserRoles(userId: string): string[];
|
|
1032
|
+
|
|
1033
|
+
/**
|
|
1034
|
+
* Get all users in a role
|
|
1035
|
+
* @param roleName - Role to get users from
|
|
1036
|
+
* @returns Array of user IDs
|
|
1037
|
+
*/
|
|
1038
|
+
getUsersInRole(roleName: string): string[];
|
|
1039
|
+
|
|
1040
|
+
/**
|
|
1041
|
+
* Get all role names
|
|
1042
|
+
* @returns Array of all role names
|
|
1043
|
+
*/
|
|
1044
|
+
getAllRoles(): string[];
|
|
1045
|
+
|
|
1046
|
+
/**
|
|
1047
|
+
* Delete a role completely
|
|
1048
|
+
* @param roleName - Role to delete
|
|
1049
|
+
* @returns True if deleted
|
|
1050
|
+
*/
|
|
1051
|
+
deleteRole(roleName: string): boolean;
|
|
1052
|
+
|
|
1053
|
+
/**
|
|
1054
|
+
* Rename a role
|
|
1055
|
+
* @param oldName - Current role name
|
|
1056
|
+
* @param newName - New role name
|
|
1057
|
+
* @returns True if renamed
|
|
1058
|
+
*/
|
|
1059
|
+
renameRole(oldName: string, newName: string): boolean;
|
|
1060
|
+
|
|
1061
|
+
/**
|
|
1062
|
+
* Check if user is owner (has 'owner' role)
|
|
1063
|
+
* @param userId - User ID to check
|
|
1064
|
+
* @returns True if user is owner
|
|
1065
|
+
*/
|
|
1066
|
+
isOwner(userId: string): boolean;
|
|
1067
|
+
|
|
1068
|
+
/**
|
|
1069
|
+
* Check if user is moderator (has 'moderator' role or from Web API)
|
|
1070
|
+
* @param userId - User ID to check
|
|
1071
|
+
* @returns True if user is moderator
|
|
1072
|
+
*/
|
|
1073
|
+
isModerator(userId: string): boolean;
|
|
1074
|
+
|
|
1075
|
+
/**
|
|
1076
|
+
* Check if user is designer (has 'designer' role or from Web API)
|
|
1077
|
+
* @param userId - User ID to check
|
|
1078
|
+
* @returns True if user is designer
|
|
1079
|
+
*/
|
|
1080
|
+
isDesigner(userId: string): boolean;
|
|
1081
|
+
|
|
1082
|
+
/**
|
|
1083
|
+
* Get all moderators (combined from role + Web API)
|
|
1084
|
+
* @returns Array of all moderator user IDs
|
|
1085
|
+
*/
|
|
1086
|
+
getAllModerators(): string[];
|
|
1087
|
+
|
|
1088
|
+
/**
|
|
1089
|
+
* Get all designers (combined from role + Web API)
|
|
1090
|
+
* @returns Array of all designer user IDs
|
|
1091
|
+
*/
|
|
1092
|
+
getAllDesigners(): string[];
|
|
1093
|
+
|
|
1094
|
+
/**
|
|
1095
|
+
* Force immediate sync with Web API and save to file
|
|
1096
|
+
* @returns Promise that resolves when sync is complete
|
|
1097
|
+
*/
|
|
1098
|
+
forceSync(): Promise<void>;
|
|
1099
|
+
|
|
1100
|
+
/**
|
|
1101
|
+
* Export roles as JSON object
|
|
1102
|
+
* @returns Object with role names as keys and user ID arrays as values
|
|
1103
|
+
*/
|
|
1104
|
+
exportToObject(): RoleObjectStructure;
|
|
1105
|
+
|
|
1106
|
+
/**
|
|
1107
|
+
* Import roles from JSON object
|
|
1108
|
+
* @param obj - Object with role names as keys and user ID arrays as values
|
|
1109
|
+
* @returns True if imported successfully
|
|
1110
|
+
*/
|
|
1111
|
+
importFromObject(obj: RoleObjectStructure): boolean;
|
|
1112
|
+
|
|
1113
|
+
/**
|
|
1114
|
+
* Clear all roles and Web API data
|
|
1115
|
+
*/
|
|
1116
|
+
clearAll(): void;
|
|
1117
|
+
|
|
1118
|
+
/**
|
|
1119
|
+
* Get sync statistics
|
|
1120
|
+
*/
|
|
1121
|
+
getStats(): PermissionStats;
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
declare class CooldownManager {
|
|
1125
|
+
/**
|
|
1126
|
+
* The manager handles individual cooldowns, global cooldowns (affecting all users),
|
|
1127
|
+
* and group-based cooldowns with rate limiting capabilities.
|
|
1128
|
+
*
|
|
1129
|
+
* @example
|
|
1130
|
+
* const cooldown = new CooldownManager();
|
|
1131
|
+
* cooldown.startAutoCleanup(); // Optional: auto-clean expired cooldowns
|
|
1132
|
+
*/
|
|
1133
|
+
constructor();
|
|
1134
|
+
|
|
1135
|
+
/**
|
|
1136
|
+
* Sets a cooldown for a specific key. If the key is already on cooldown,
|
|
1137
|
+
* returns false and doesn't override the existing cooldown.
|
|
1138
|
+
*
|
|
1139
|
+
* @param key - Unique identifier for the cooldown. Common patterns:
|
|
1140
|
+
* - `user:{userId}:{command}` for user-specific command cooldowns
|
|
1141
|
+
* - `item:{itemId}:{userId}` for item usage cooldowns
|
|
1142
|
+
* - `action:{action}:{target}` for specific action cooldowns
|
|
1143
|
+
* @param durationMs - Cooldown duration in milliseconds
|
|
1144
|
+
* @param metadata - Optional metadata to store with the cooldown for later retrieval
|
|
1145
|
+
* @returns `true` if cooldown was set successfully, `false` if key was already on cooldown
|
|
1146
|
+
*
|
|
1147
|
+
* @example
|
|
1148
|
+
* // Create a variable for the bot cooldown
|
|
1149
|
+
* const cooldown = bot.utils.cooldown
|
|
1150
|
+
*
|
|
1151
|
+
* // Set a 5-second cooldown for a user's dance command
|
|
1152
|
+
* const wasSet = cooldown.set(`user:${userId}:!dance`, 5000, {
|
|
1153
|
+
* command: 'dance',
|
|
1154
|
+
* timestamp: Date.now()
|
|
1155
|
+
* });
|
|
1156
|
+
*
|
|
1157
|
+
* @example
|
|
1158
|
+
* // Prevent item spam - 30 seconds between using the same item
|
|
1159
|
+
* cooldown.set(`item:teleport_scroll:${userId}`, 30000, {
|
|
1160
|
+
* itemName: 'Teleport Scroll',
|
|
1161
|
+
* usageCount: 1
|
|
1162
|
+
* });
|
|
1163
|
+
*/
|
|
1164
|
+
set(key: string, durationMs: number, metadata?: CooldownMetadata): boolean;
|
|
1165
|
+
|
|
1166
|
+
/**
|
|
1167
|
+
* Checks if a key is currently on cooldown. Automatically cleans up
|
|
1168
|
+
* expired cooldowns unless disabled.
|
|
1169
|
+
*
|
|
1170
|
+
* @param key - The key to check for active cooldown
|
|
1171
|
+
* @param autoCleanup - If `true` (default), automatically removes expired cooldowns
|
|
1172
|
+
* @returns Cooldown information object if active, `null` if not on cooldown or expired
|
|
1173
|
+
*
|
|
1174
|
+
* @example
|
|
1175
|
+
* // Create a variable for the bot cooldown
|
|
1176
|
+
* const cooldown = bot.utils.cooldown
|
|
1177
|
+
*
|
|
1178
|
+
* const cooldownInfo = cooldown.check(`user:${userId}:!dance`);
|
|
1179
|
+
* if (cooldownInfo) {
|
|
1180
|
+
* // Still on cooldown
|
|
1181
|
+
* console.log(`Wait ${cooldownInfo.remainingSeconds} more seconds`);
|
|
1182
|
+
* console.log(`Progress: ${(cooldownInfo.progress * 100).toFixed(1)}% complete`);
|
|
1183
|
+
* }
|
|
1184
|
+
*
|
|
1185
|
+
* @example
|
|
1186
|
+
* // Manual cleanup control
|
|
1187
|
+
* const cooldownInfo = cooldown.check(key, false); // Don't auto-clean
|
|
1188
|
+
* if (cooldownInfo && cooldownInfo.remainingMs < 100) {
|
|
1189
|
+
* // Almost expired, handle special case
|
|
1190
|
+
* }
|
|
1191
|
+
*/
|
|
1192
|
+
check(key: string, autoCleanup?: boolean): CooldownInfo | null;
|
|
1193
|
+
|
|
1194
|
+
/**
|
|
1195
|
+
* Gets the remaining time in milliseconds for a cooldown.
|
|
1196
|
+
* Returns 0 if the key is not on cooldown.
|
|
1197
|
+
*
|
|
1198
|
+
* @param key - The key to check
|
|
1199
|
+
* @returns Milliseconds remaining until cooldown expires, or 0 if no active cooldown
|
|
1200
|
+
*
|
|
1201
|
+
* @example
|
|
1202
|
+
* // Create a variable for the bot cooldown
|
|
1203
|
+
* const cooldown = bot.utils.cooldown
|
|
1204
|
+
*
|
|
1205
|
+
* const remaining = cooldown.getRemaining(`user:${userId}:!dance`);
|
|
1206
|
+
* if (remaining > 0) {
|
|
1207
|
+
* // Format and display to user
|
|
1208
|
+
* const seconds = Math.ceil(remaining / 1000);
|
|
1209
|
+
* bot.whisper.send(userId, `Please wait ${seconds} seconds`);
|
|
1210
|
+
* }
|
|
1211
|
+
*/
|
|
1212
|
+
getRemaining(key: string): number;
|
|
1213
|
+
|
|
1214
|
+
/**
|
|
1215
|
+
* Attempts to execute an action if not on cooldown. If the key is not on cooldown,
|
|
1216
|
+
* sets the cooldown and optionally executes the callback. If on cooldown,
|
|
1217
|
+
* returns information about the remaining time without executing the callback.
|
|
1218
|
+
*
|
|
1219
|
+
* @param key - The key to check and set cooldown for
|
|
1220
|
+
* @param durationMs - Cooldown duration to set if successful
|
|
1221
|
+
* @param callback - Optional function to execute if not on cooldown
|
|
1222
|
+
* @returns Result object containing success status, remaining time (if on cooldown),
|
|
1223
|
+
* or execution result (if callback was executed)
|
|
1224
|
+
*
|
|
1225
|
+
* @example
|
|
1226
|
+
* // Create a variable for the bot cooldown
|
|
1227
|
+
* const cooldown = bot.utils.cooldown
|
|
1228
|
+
*
|
|
1229
|
+
* // Basic usage with callback
|
|
1230
|
+
* const result = cooldown.attempt(`user:${userId}:!dance`, 3000, () => {
|
|
1231
|
+
* // This only executes if not on cooldown
|
|
1232
|
+
* bot.player.emote('dance', userId);
|
|
1233
|
+
* return 'dance_started';
|
|
1234
|
+
* });
|
|
1235
|
+
*
|
|
1236
|
+
* if (!result.success) {
|
|
1237
|
+
* // On cooldown - inform user
|
|
1238
|
+
* bot.whisper.send(userId, `Wait ${result.remainingSeconds} seconds`);
|
|
1239
|
+
* } else if (result.executed) {
|
|
1240
|
+
* // Callback was executed
|
|
1241
|
+
* console.log('Result:', result.result);
|
|
1242
|
+
* }
|
|
1243
|
+
*
|
|
1244
|
+
* @example
|
|
1245
|
+
* // Without callback (just checks and sets)
|
|
1246
|
+
* const result = cooldown.attempt(`user:${userId}:action`, 5000);
|
|
1247
|
+
* if (result.success) {
|
|
1248
|
+
* // Not on cooldown, cooldown was set
|
|
1249
|
+
* // Proceed with action...
|
|
1250
|
+
* }
|
|
1251
|
+
*/
|
|
1252
|
+
attempt(key: string, durationMs: number, callback?: (() => any) | null): AttemptResult;
|
|
1253
|
+
|
|
1254
|
+
/**
|
|
1255
|
+
* Removes an active cooldown for a specific key.
|
|
1256
|
+
*
|
|
1257
|
+
* @param key - The key to remove cooldown for
|
|
1258
|
+
* @returns `true` if cooldown existed and was removed, `false` if no cooldown existed
|
|
1259
|
+
*
|
|
1260
|
+
* @example
|
|
1261
|
+
* // Create a variable for the bot cooldown
|
|
1262
|
+
* const cooldown = bot.utils.cooldown
|
|
1263
|
+
*
|
|
1264
|
+
* // Admin override - remove user's cooldown
|
|
1265
|
+
* if (isAdmin(adminId)) {
|
|
1266
|
+
* const removed = cooldown.remove(`user:${targetUserId}:!dance`);
|
|
1267
|
+
* if (removed) {
|
|
1268
|
+
* bot.whisper.send(targetUserId, 'Your cooldown was cleared by admin');
|
|
1269
|
+
* }
|
|
1270
|
+
* }
|
|
1271
|
+
*
|
|
1272
|
+
* @example
|
|
1273
|
+
* // Error recovery - remove stuck cooldown
|
|
1274
|
+
* if (errorOccurred) {
|
|
1275
|
+
* cooldown.remove(`user:${userId}:!purchase`);
|
|
1276
|
+
* // Allow user to retry
|
|
1277
|
+
* }
|
|
1278
|
+
*/
|
|
1279
|
+
remove(key: string): boolean;
|
|
1280
|
+
|
|
1281
|
+
/**
|
|
1282
|
+
* Clears all cooldowns, or only those matching a prefix.
|
|
1283
|
+
*
|
|
1284
|
+
* @param prefix - Optional prefix to filter keys. If provided, only clears
|
|
1285
|
+
* cooldowns whose keys start with this prefix.
|
|
1286
|
+
* @returns Number of cooldowns that were cleared
|
|
1287
|
+
*
|
|
1288
|
+
* @example
|
|
1289
|
+
* // Create a variable for the bot cooldown
|
|
1290
|
+
* const cooldown = bot.utils.cooldown
|
|
1291
|
+
*
|
|
1292
|
+
* // Clear all cooldowns (server reset)
|
|
1293
|
+
* const clearedAll = cooldown.clear();
|
|
1294
|
+
* console.log(`Cleared ${clearedAll} cooldowns`);
|
|
1295
|
+
*
|
|
1296
|
+
* @example
|
|
1297
|
+
* // Clear only user-related cooldowns
|
|
1298
|
+
* const clearedUsers = cooldown.clear('user:');
|
|
1299
|
+
*
|
|
1300
|
+
* @example
|
|
1301
|
+
* // Clear cooldowns for specific user
|
|
1302
|
+
* const clearedUser = cooldown.clear(`user:${userId}:`);
|
|
1303
|
+
*
|
|
1304
|
+
* @example
|
|
1305
|
+
* // Clear daily cooldowns
|
|
1306
|
+
* const clearedDaily = cooldown.clear('daily:');
|
|
1307
|
+
*/
|
|
1308
|
+
clear(prefix?: string | null): number;
|
|
1309
|
+
|
|
1310
|
+
/**
|
|
1311
|
+
* Sets a global cooldown that affects all users. Useful for system-wide
|
|
1312
|
+
* events, maintenance, or world events.
|
|
1313
|
+
*
|
|
1314
|
+
* @param action - Unique identifier for the global action
|
|
1315
|
+
* @param durationMs - Duration in milliseconds
|
|
1316
|
+
* @returns `true` if global cooldown was set, `false` if already active
|
|
1317
|
+
*
|
|
1318
|
+
* @example
|
|
1319
|
+
* // System maintenance
|
|
1320
|
+
* cooldown.setGlobal('maintenance', 300000); // 5 minutes
|
|
1321
|
+
*
|
|
1322
|
+
* @example
|
|
1323
|
+
* // World boss spawn cooldown
|
|
1324
|
+
* cooldown.setGlobal('world_boss_spawn', 3600000); // 1 hour
|
|
1325
|
+
*
|
|
1326
|
+
* @example
|
|
1327
|
+
* // Limited-time event
|
|
1328
|
+
* cooldown.setGlobal('halloween_event', 604800000); // 7 days
|
|
1329
|
+
*/
|
|
1330
|
+
setGlobal(action: string, durationMs: number): boolean;
|
|
1331
|
+
|
|
1332
|
+
/**
|
|
1333
|
+
* Checks if a global cooldown is currently active.
|
|
1334
|
+
*
|
|
1335
|
+
* @param action - The global action identifier
|
|
1336
|
+
* @returns Global cooldown information if active, `null` if not active
|
|
1337
|
+
*
|
|
1338
|
+
* @example
|
|
1339
|
+
* // Create a variable for the bot cooldown
|
|
1340
|
+
* const cooldown = bot.utils.cooldown
|
|
1341
|
+
*
|
|
1342
|
+
* // Check if system is in maintenance
|
|
1343
|
+
* const maintenance = cooldown.checkGlobal('maintenance');
|
|
1344
|
+
* if (maintenance) {
|
|
1345
|
+
* bot.message.send(`🛠️ Maintenance in progress for ${cooldown.formatTime(maintenance.remainingMs)}`);
|
|
1346
|
+
* return;
|
|
1347
|
+
* }
|
|
1348
|
+
*
|
|
1349
|
+
* @example
|
|
1350
|
+
* // Check world boss availability
|
|
1351
|
+
* const bossCooldown = cooldown.checkGlobal('world_boss_spawn');
|
|
1352
|
+
* if (bossCooldown) {
|
|
1353
|
+
* const timeStr = cooldown.formatTime(bossCooldown.remainingMs);
|
|
1354
|
+
* bot.message.send(`The world boss will respawn in ${timeStr}`);
|
|
1355
|
+
* } else {
|
|
1356
|
+
* // Spawn boss logic
|
|
1357
|
+
* }
|
|
1358
|
+
*/
|
|
1359
|
+
checkGlobal(action: string): GlobalCooldownInfo | null;
|
|
1360
|
+
|
|
1361
|
+
/**
|
|
1362
|
+
* Creates a cooldown group for managing limited resources with
|
|
1363
|
+
* configurable concurrency and per-user limits.
|
|
1364
|
+
*
|
|
1365
|
+
* @param groupName - Unique name for the group
|
|
1366
|
+
* @param config - Configuration object for the group
|
|
1367
|
+
*
|
|
1368
|
+
* @example
|
|
1369
|
+
* // Create a variable for the bot cooldown
|
|
1370
|
+
* const cooldown = bot.utils.cooldown
|
|
1371
|
+
*
|
|
1372
|
+
* // Create a teleporter with max 3 concurrent users, 10s cooldown per user
|
|
1373
|
+
* cooldown.createGroup('main_teleporter', {
|
|
1374
|
+
* defaultDuration: 10000,
|
|
1375
|
+
* maxConcurrent: 3,
|
|
1376
|
+
* perUserLimit: 1
|
|
1377
|
+
* });
|
|
1378
|
+
*
|
|
1379
|
+
* @example
|
|
1380
|
+
* // Game table - only 1 game at a time, 5 minute games
|
|
1381
|
+
* cooldown.createGroup('poker_table', {
|
|
1382
|
+
* defaultDuration: 300000,
|
|
1383
|
+
* maxConcurrent: 1,
|
|
1384
|
+
* perUserLimit: 1
|
|
1385
|
+
* });
|
|
1386
|
+
*
|
|
1387
|
+
* @example
|
|
1388
|
+
* // Fishing spot - many can fish, but limited lines per user
|
|
1389
|
+
* cooldown.createGroup('fishing_spot', {
|
|
1390
|
+
* defaultDuration: 30000,
|
|
1391
|
+
* maxConcurrent: 10,
|
|
1392
|
+
* perUserLimit: 3
|
|
1393
|
+
* });
|
|
1394
|
+
*/
|
|
1395
|
+
createGroup(groupName: string, config?: Partial<GroupConfig>): void;
|
|
1396
|
+
|
|
1397
|
+
/**
|
|
1398
|
+
* Checks if a user can perform an action in a group, considering
|
|
1399
|
+
* max concurrent limits and per-user limits.
|
|
1400
|
+
*
|
|
1401
|
+
* @param groupName - The group to check
|
|
1402
|
+
* @param userId - Optional user ID to check per-user limits
|
|
1403
|
+
* @returns Object indicating if action is allowed and reason if not
|
|
1404
|
+
*
|
|
1405
|
+
* @example
|
|
1406
|
+
* // Create a variable for the bot cooldown
|
|
1407
|
+
* const cooldown = bot.utils.cooldown
|
|
1408
|
+
*
|
|
1409
|
+
* // Check if user can teleport
|
|
1410
|
+
* const check = cooldown.checkGroup('main_teleporter', userId);
|
|
1411
|
+
* if (!check.allowed) {
|
|
1412
|
+
* switch (check.reason) {
|
|
1413
|
+
* case 'max_concurrent':
|
|
1414
|
+
* return 'Teleporter is busy! Wait for others to finish.';
|
|
1415
|
+
* case 'user_limit':
|
|
1416
|
+
* return 'You are already teleporting!';
|
|
1417
|
+
* case 'user_cooldown':
|
|
1418
|
+
* return `You just teleported! Wait ${check.remainingSeconds}s`;
|
|
1419
|
+
* }
|
|
1420
|
+
* }
|
|
1421
|
+
*
|
|
1422
|
+
* @example
|
|
1423
|
+
* // Check resource availability without user context
|
|
1424
|
+
* const resourceCheck = cooldown.checkGroup('mining_vein');
|
|
1425
|
+
* if (!resourceCheck.allowed && resourceCheck.reason === 'max_concurrent') {
|
|
1426
|
+
* return 'This mining vein is fully occupied!';
|
|
1427
|
+
* }
|
|
1428
|
+
*/
|
|
1429
|
+
checkGroup(groupName: string, userId?: string | null): CheckGroupResult;
|
|
1430
|
+
|
|
1431
|
+
/**
|
|
1432
|
+
* Starts an action in a group, consuming a slot and setting user cooldown.
|
|
1433
|
+
* Returns detailed result including unique action ID for later ending.
|
|
1434
|
+
*
|
|
1435
|
+
* @param groupName - The group to start action in
|
|
1436
|
+
* @param actionId - Unique identifier for this specific action instance
|
|
1437
|
+
* @param userId - Optional user ID for per-user tracking
|
|
1438
|
+
* @returns Detailed result with success status and action information
|
|
1439
|
+
*
|
|
1440
|
+
* @example
|
|
1441
|
+
* // Create a variable for the bot cooldown
|
|
1442
|
+
* const cooldown = bot.utils.cooldown
|
|
1443
|
+
*
|
|
1444
|
+
* // Start a teleport action
|
|
1445
|
+
* const actionId = `teleport:${Date.now()}:${userId}`;
|
|
1446
|
+
* const result = cooldown.startGroupAction('main_teleporter', actionId, userId);
|
|
1447
|
+
*
|
|
1448
|
+
* if (!result.success) {
|
|
1449
|
+
* return result.message; // "Teleporter is busy!" etc.
|
|
1450
|
+
* }
|
|
1451
|
+
*
|
|
1452
|
+
* // Store actionId for later cleanup
|
|
1453
|
+
* currentTeleports.set(userId, {
|
|
1454
|
+
* actionId: result.actionId,
|
|
1455
|
+
* startedAt: result.startedAt
|
|
1456
|
+
* });
|
|
1457
|
+
*
|
|
1458
|
+
* // When teleport completes
|
|
1459
|
+
* cooldown.endGroupAction('main_teleporter', result.actionId);
|
|
1460
|
+
*
|
|
1461
|
+
* @example
|
|
1462
|
+
* // Start a game session
|
|
1463
|
+
* const gameId = `chess:${Date.now()}:${player1}:${player2}`;
|
|
1464
|
+
* const gameResult = cooldown.startGroupAction('chess_table', gameId, player1);
|
|
1465
|
+
* // Note: Only first player consumes per-user limit
|
|
1466
|
+
*/
|
|
1467
|
+
startGroupAction(groupName: string, actionId: string, userId?: string | null): StartGroupResult;
|
|
1468
|
+
|
|
1469
|
+
/**
|
|
1470
|
+
* Ends an action in a group, freeing up the slot for others.
|
|
1471
|
+
*
|
|
1472
|
+
* @param groupName - The group containing the action
|
|
1473
|
+
* @param actionId - The unique action ID to end
|
|
1474
|
+
* @returns `true` if action existed and was ended, `false` if not found
|
|
1475
|
+
*
|
|
1476
|
+
* @example
|
|
1477
|
+
* // Create a variable for the bot cooldown
|
|
1478
|
+
* const cooldown = bot.utils.cooldown
|
|
1479
|
+
*
|
|
1480
|
+
* // When teleport completes
|
|
1481
|
+
* const actionId = currentTeleports.get(userId)?.actionId;
|
|
1482
|
+
* if (actionId) {
|
|
1483
|
+
* const ended = cooldown.endGroupAction('main_teleporter', actionId);
|
|
1484
|
+
* if (ended) {
|
|
1485
|
+
* currentTeleports.delete(userId);
|
|
1486
|
+
* bot.whisper.send(userId, 'Teleport complete!');
|
|
1487
|
+
* }
|
|
1488
|
+
* }
|
|
1489
|
+
*
|
|
1490
|
+
* @example
|
|
1491
|
+
* // Game completion
|
|
1492
|
+
* function endGame(gameId: string) {
|
|
1493
|
+
* cooldown.endGroupAction('poker_table', gameId);
|
|
1494
|
+
* // Also remove user cooldowns if needed
|
|
1495
|
+
* cooldown.remove(`poker_cooldown:${player1}`);
|
|
1496
|
+
* cooldown.remove(`poker_cooldown:${player2}`);
|
|
1497
|
+
* }
|
|
1498
|
+
*/
|
|
1499
|
+
endGroupAction(groupName: string, actionId: string): boolean;
|
|
1500
|
+
|
|
1501
|
+
/**
|
|
1502
|
+
* Gets all active cooldowns for a specific user. Useful for displaying
|
|
1503
|
+
* user's current restrictions or detecting potential abuse.
|
|
1504
|
+
*
|
|
1505
|
+
* @param userId - The user ID to get cooldowns for
|
|
1506
|
+
* @returns Array of active cooldown objects for the user
|
|
1507
|
+
*
|
|
1508
|
+
* @example
|
|
1509
|
+
* // Create a variable for the bot cooldown
|
|
1510
|
+
* const cooldown = bot.utils.cooldown
|
|
1511
|
+
*
|
|
1512
|
+
* // Display user's active cooldowns
|
|
1513
|
+
* const userCooldowns = cooldown.getUserCooldowns(userId);
|
|
1514
|
+
* if (userCooldowns.length > 0) {
|
|
1515
|
+
* const cooldownList = userCooldowns.map(c =>
|
|
1516
|
+
* `${c.metadata.command || 'Action'}: ${Math.ceil(c.remainingMs/1000)}s`
|
|
1517
|
+
* ).join('\n');
|
|
1518
|
+
* bot.whisper.send(userId, `Your active cooldowns:\n${cooldownList}`);
|
|
1519
|
+
* }
|
|
1520
|
+
*
|
|
1521
|
+
* @example
|
|
1522
|
+
* // Detect potential abusers
|
|
1523
|
+
* const userCooldowns = cooldown.getUserCooldowns(userId);
|
|
1524
|
+
* if (userCooldowns.length > 15) {
|
|
1525
|
+
* bot.utils.logger.warn('High cooldown count', { userId, count: userCooldowns.length });
|
|
1526
|
+
* // Consider temporary restriction
|
|
1527
|
+
* }
|
|
1528
|
+
*
|
|
1529
|
+
* @example
|
|
1530
|
+
* // Admin view of user restrictions
|
|
1531
|
+
* function getUserStatus(userId: string) {
|
|
1532
|
+
* const cooldowns = cooldown.getUserCooldowns(userId);
|
|
1533
|
+
* return {
|
|
1534
|
+
* userId,
|
|
1535
|
+
* activeRestrictions: cooldowns.length,
|
|
1536
|
+
* restrictions: cooldowns.map(c => ({
|
|
1537
|
+
* type: c.key.split(':')[1],
|
|
1538
|
+
* remaining: cooldown.formatTime(c.remainingMs),
|
|
1539
|
+
* reason: c.metadata.reason
|
|
1540
|
+
* }))
|
|
1541
|
+
* };
|
|
1542
|
+
* }
|
|
1543
|
+
*/
|
|
1544
|
+
getUserCooldowns(userId: string): UserCooldown[];
|
|
1545
|
+
|
|
1546
|
+
/**
|
|
1547
|
+
* Gets comprehensive usage statistics and current state of the cooldown manager.
|
|
1548
|
+
* Useful for monitoring, debugging, and performance analysis.
|
|
1549
|
+
*
|
|
1550
|
+
* @returns Statistics object containing usage metrics, current counts, and memory estimates
|
|
1551
|
+
*
|
|
1552
|
+
* @example
|
|
1553
|
+
* // Create a variable for the bot cooldown
|
|
1554
|
+
* const cooldown = bot.utils.cooldown
|
|
1555
|
+
*
|
|
1556
|
+
* // Periodic monitoring
|
|
1557
|
+
* setInterval(() => {
|
|
1558
|
+
* const stats = cooldown.getStats();
|
|
1559
|
+
* const successRate = (stats.successfulActions / stats.totalChecks * 100).toFixed(1);
|
|
1560
|
+
*
|
|
1561
|
+
* console.log(`
|
|
1562
|
+
* Cooldown Stats:
|
|
1563
|
+
* - Success Rate: ${successRate}%
|
|
1564
|
+
* - Active Cooldowns: ${stats.activeCooldowns}
|
|
1565
|
+
* - Memory Usage: ${stats.memoryUsage.total}
|
|
1566
|
+
* - Blocked Actions: ${stats.blockedActions}
|
|
1567
|
+
* `);
|
|
1568
|
+
*
|
|
1569
|
+
* // Check group status
|
|
1570
|
+
* for (const [groupName, groupStats] of Object.entries(stats.groups)) {
|
|
1571
|
+
* console.log(`${groupName}: ${groupStats.active}/${groupStats.config.maxConcurrent} active`);
|
|
1572
|
+
* }
|
|
1573
|
+
* }, 60000); // Log every minute
|
|
1574
|
+
*
|
|
1575
|
+
* @example
|
|
1576
|
+
* // Dashboard endpoint
|
|
1577
|
+
* function getSystemStatus() {
|
|
1578
|
+
* const stats = cooldown.getStats();
|
|
1579
|
+
* return {
|
|
1580
|
+
* uptime: Date.now() - startTime,
|
|
1581
|
+
* cooldownStats: stats,
|
|
1582
|
+
* health: stats.activeCooldowns < 1000 ? 'healthy' : 'warning'
|
|
1583
|
+
* };
|
|
1584
|
+
* }
|
|
1585
|
+
*
|
|
1586
|
+
* @example
|
|
1587
|
+
* // Debugging high memory usage
|
|
1588
|
+
* if (memoryIsHigh()) {
|
|
1589
|
+
* const stats = cooldown.getStats();
|
|
1590
|
+
* console.log('Memory breakdown:', stats.memoryUsage);
|
|
1591
|
+
* // Clear old cooldowns if memory is high
|
|
1592
|
+
* if (stats.activeCooldowns > 500) {
|
|
1593
|
+
* cooldown.clear('old:'); // Assuming you prefix old cooldowns
|
|
1594
|
+
* }
|
|
1595
|
+
* }
|
|
1596
|
+
*/
|
|
1597
|
+
getStats(): CooldownManagerStats;
|
|
1598
|
+
|
|
1599
|
+
/**
|
|
1600
|
+
* Starts automatic background cleanup of expired cooldowns.
|
|
1601
|
+
* Recommended for long-running applications to prevent memory buildup.
|
|
1602
|
+
*
|
|
1603
|
+
* @param intervalMs - Cleanup interval in milliseconds (default: 60000 = 1 minute)
|
|
1604
|
+
* @returns The interval ID that can be used to stop cleanup
|
|
1605
|
+
*
|
|
1606
|
+
* @example
|
|
1607
|
+
* // Create a variable for the bot cooldown
|
|
1608
|
+
* const cooldown = bot.utils.cooldown
|
|
1609
|
+
*
|
|
1610
|
+
* // Start with default 1-minute interval
|
|
1611
|
+
* cooldown.startAutoCleanup();
|
|
1612
|
+
*
|
|
1613
|
+
* @example
|
|
1614
|
+
* // More frequent cleanup for high-traffic bots
|
|
1615
|
+
* cooldown.startAutoCleanup(30000); // Every 30 seconds
|
|
1616
|
+
*
|
|
1617
|
+
* @example
|
|
1618
|
+
* // Store interval for management
|
|
1619
|
+
* const cleanupInterval = cooldown.startAutoCleanup(60000);
|
|
1620
|
+
*
|
|
1621
|
+
* // Later, if needed
|
|
1622
|
+
* clearInterval(cleanupInterval);
|
|
1623
|
+
* // Or use stopAutoCleanup()
|
|
1624
|
+
*/
|
|
1625
|
+
startAutoCleanup(intervalMs?: number): NodeJS.Timeout;
|
|
1626
|
+
|
|
1627
|
+
/**
|
|
1628
|
+
* Stops the automatic cleanup interval if it's running.
|
|
1629
|
+
*
|
|
1630
|
+
* @example
|
|
1631
|
+
* // Create a variable for the bot cooldown
|
|
1632
|
+
* const cooldown = bot.utils.cooldown
|
|
1633
|
+
*
|
|
1634
|
+
* // Graceful shutdown
|
|
1635
|
+
* function shutdown() {
|
|
1636
|
+
* cooldown.stopAutoCleanup();
|
|
1637
|
+
* cooldown.destroy();
|
|
1638
|
+
* process.exit(0);
|
|
1639
|
+
* }
|
|
1640
|
+
*
|
|
1641
|
+
* @example
|
|
1642
|
+
* // Temporary pause
|
|
1643
|
+
* cooldown.stopAutoCleanup();
|
|
1644
|
+
* // Do some maintenance...
|
|
1645
|
+
* cooldown.startAutoCleanup(); // Resume
|
|
1646
|
+
*/
|
|
1647
|
+
stopAutoCleanup(): void;
|
|
1648
|
+
|
|
1649
|
+
/**
|
|
1650
|
+
* Completely destroys all cooldown data and stops auto-cleanup.
|
|
1651
|
+
* Resets the manager to its initial empty state.
|
|
1652
|
+
*
|
|
1653
|
+
* @example
|
|
1654
|
+
* // Create a variable for the bot cooldown
|
|
1655
|
+
* const cooldown = bot.utils.cooldown
|
|
1656
|
+
*
|
|
1657
|
+
* // Server reset
|
|
1658
|
+
* function resetServer() {
|
|
1659
|
+
* cooldown.destroy();
|
|
1660
|
+
* console.log('All cooldowns cleared');
|
|
1661
|
+
* // Reinitialize if needed
|
|
1662
|
+
* cooldown.startAutoCleanup();
|
|
1663
|
+
* }
|
|
1664
|
+
*
|
|
1665
|
+
* @example
|
|
1666
|
+
* // Testing - clean between tests
|
|
1667
|
+
* beforeEach(() => {
|
|
1668
|
+
* cooldown.destroy();
|
|
1669
|
+
* });
|
|
1670
|
+
*
|
|
1671
|
+
* @example
|
|
1672
|
+
* // Memory management
|
|
1673
|
+
* if (memoryPressure > 0.9) { // 90% memory usage
|
|
1674
|
+
* cooldown.destroy();
|
|
1675
|
+
* // Recreate essential groups
|
|
1676
|
+
* cooldown.createGroup('essential_teleporter', {...});
|
|
1677
|
+
* }
|
|
1678
|
+
*/
|
|
1679
|
+
destroy(): void;
|
|
1680
|
+
|
|
1681
|
+
/**
|
|
1682
|
+
* Static utility method to format milliseconds into a human-readable string.
|
|
1683
|
+
* Automatically selects appropriate time units (ms, seconds, minutes, hours, days).
|
|
1684
|
+
*
|
|
1685
|
+
* @param ms - Milliseconds to format
|
|
1686
|
+
* @returns Formatted time string (e.g., "2m 5s", "1h 30m", "500ms")
|
|
1687
|
+
*
|
|
1688
|
+
* @example
|
|
1689
|
+
* // Create a variable for the bot cooldown
|
|
1690
|
+
* const cooldown = bot.utils.cooldown
|
|
1691
|
+
*
|
|
1692
|
+
* // Display remaining time to users
|
|
1693
|
+
* const remaining = cooldown.getRemaining(`user:${userId}:!command`);
|
|
1694
|
+
* if (remaining > 0) {
|
|
1695
|
+
* const timeStr = cooldown.formatTime(remaining);
|
|
1696
|
+
* bot.whisper.send(userId, `Please wait ${timeStr}`);
|
|
1697
|
+
* }
|
|
1698
|
+
*
|
|
1699
|
+
* @example
|
|
1700
|
+
* // Different formatting examples
|
|
1701
|
+
* cooldown.formatTime(500); // "500ms"
|
|
1702
|
+
* cooldown.formatTime(1500); // "2s" (rounded up)
|
|
1703
|
+
* cooldown.formatTime(65000); // "1m 5s"
|
|
1704
|
+
* cooldown.formatTime(90000); // "1m 30s"
|
|
1705
|
+
* cooldown.formatTime(7200000); // "2h"
|
|
1706
|
+
* cooldown.formatTime(172800000); // "2d"
|
|
1707
|
+
* cooldown.formatTime(0); // "0s"
|
|
1708
|
+
*
|
|
1709
|
+
* @example
|
|
1710
|
+
* // Use in game timers
|
|
1711
|
+
* function displayBossTimer(remainingMs: number) {
|
|
1712
|
+
* const timeStr = cooldown.formatTime(remainingMs);
|
|
1713
|
+
* bot.message.send(`Boss respawns in ${timeStr}`);
|
|
1714
|
+
* }
|
|
1715
|
+
*/
|
|
1716
|
+
static formatTime(ms: number): string;
|
|
1717
|
+
}
|
|
1718
|
+
|
|
1719
|
+
/**
|
|
1720
|
+
* Hidden channel system for bot-to-bot communication
|
|
1721
|
+
* Messages are broadcast to all bots in the same room
|
|
1722
|
+
*/
|
|
1723
|
+
declare class Channel {
|
|
1724
|
+
/**
|
|
1725
|
+
* Send a message to the hidden channel
|
|
1726
|
+
* All bots in the room will receive this message
|
|
1727
|
+
*
|
|
1728
|
+
* @param message - The message content to send
|
|
1729
|
+
* @param tags - Tags for categorizing and filtering the message
|
|
1730
|
+
* @returns Promise resolving to true if sent successfully, false otherwise
|
|
1731
|
+
*
|
|
1732
|
+
* @example
|
|
1733
|
+
* ```typescript
|
|
1734
|
+
* // Send a JSON message with tags
|
|
1735
|
+
* const success = await bot.channel.send(
|
|
1736
|
+
* JSON.stringify({ username: 'Player1', score: 100 }),
|
|
1737
|
+
* ['game', 'score-update']
|
|
1738
|
+
* );
|
|
1739
|
+
*
|
|
1740
|
+
* // Send a plain text message
|
|
1741
|
+
* await bot.channel.send('Game starting in 10 seconds', ['game', 'countdown']);
|
|
1742
|
+
*
|
|
1743
|
+
* // Send without tags (global broadcast)
|
|
1744
|
+
* await bot.channel.send('System restarting');
|
|
1745
|
+
* ```
|
|
1746
|
+
*/
|
|
1747
|
+
send(message: string, tags?: string[]): Promise<boolean>;
|
|
1748
|
+
|
|
1749
|
+
/**
|
|
1750
|
+
* Listen for messages with specific tags
|
|
1751
|
+
* The callback receives the full ChannelMessage object
|
|
1752
|
+
*
|
|
1753
|
+
* @param tags - Tag(s) to listen for. All tags must be present in message.
|
|
1754
|
+
* @param callback - Function called when matching message arrives
|
|
1755
|
+
* @returns Listener ID for unsubscribing, or null on error
|
|
1756
|
+
*
|
|
1757
|
+
* @example
|
|
1758
|
+
* ```typescript
|
|
1759
|
+
* // Listen for moderation events
|
|
1760
|
+
* const listenerId = bot.channel.on(['moderation', 'kick'], (data) => {
|
|
1761
|
+
* const event = JSON.parse(data.message);
|
|
1762
|
+
* console.log(`${event.username} was kicked by ${data.senderId}`);
|
|
1763
|
+
* });
|
|
1764
|
+
*
|
|
1765
|
+
* // Listen for game start with multiple tags
|
|
1766
|
+
* bot.channel.on(['game', 'tic-tac-toe', 'start'], (data) => {
|
|
1767
|
+
* console.log(`Game starting: ${data.message}`);
|
|
1768
|
+
* startGame();
|
|
1769
|
+
* });
|
|
1770
|
+
*
|
|
1771
|
+
* // Listen for any message with a specific tag
|
|
1772
|
+
* bot.channel.on('system', (data) => {
|
|
1773
|
+
* console.log(`System message: ${data.message}`);
|
|
1774
|
+
* });
|
|
1775
|
+
* ```
|
|
1776
|
+
*/
|
|
1777
|
+
on(tags: string | string[], callback: ChannelListenerCallback): string | null;
|
|
1778
|
+
|
|
1779
|
+
/**
|
|
1780
|
+
* Listen once for messages with specific tags
|
|
1781
|
+
* Automatically unsubscribes after first matching message
|
|
1782
|
+
*
|
|
1783
|
+
* @param tags - Tag(s) to listen for
|
|
1784
|
+
* @param callback - Function called when matching message arrives
|
|
1785
|
+
* @returns Listener ID for manual unsubscription, or null on error
|
|
1786
|
+
*
|
|
1787
|
+
* @example
|
|
1788
|
+
* ```typescript
|
|
1789
|
+
* // Wait for shutdown signal
|
|
1790
|
+
* bot.channel.once(['system', 'shutdown'], (data) => {
|
|
1791
|
+
* console.log('Received shutdown command');
|
|
1792
|
+
* bot.disconnect();
|
|
1793
|
+
* });
|
|
1794
|
+
*
|
|
1795
|
+
* // Wait for game initialization
|
|
1796
|
+
* bot.channel.once(['game', 'init-complete'], (data) => {
|
|
1797
|
+
* console.log('Game initialized, starting...');
|
|
1798
|
+
* });
|
|
1799
|
+
* ```
|
|
1800
|
+
*/
|
|
1801
|
+
once(tags: string | string[], callback: ChannelListenerCallback): string | null;
|
|
1802
|
+
|
|
1803
|
+
/**
|
|
1804
|
+
* Remove a specific listener
|
|
1805
|
+
*
|
|
1806
|
+
* @param listenerId - ID returned by on() or once()
|
|
1807
|
+
* @returns true if listener was removed, false if not found
|
|
1808
|
+
*
|
|
1809
|
+
* @example
|
|
1810
|
+
* ```typescript
|
|
1811
|
+
* // Store listener ID when subscribing
|
|
1812
|
+
* const listenerId = bot.channel.on(['game'], handler);
|
|
1813
|
+
*
|
|
1814
|
+
* // Later, remove the listener
|
|
1815
|
+
* const removed = bot.channel.off(listenerId);
|
|
1816
|
+
* console.log(`Listener removed: ${removed}`);
|
|
1817
|
+
* ```
|
|
1818
|
+
*/
|
|
1819
|
+
off(listenerId: string): boolean;
|
|
1820
|
+
|
|
1821
|
+
/**
|
|
1822
|
+
* Remove all listeners for specific tags
|
|
1823
|
+
*
|
|
1824
|
+
* @param tags - Tag(s) to remove listeners for
|
|
1825
|
+
* @returns Number of listeners removed
|
|
1826
|
+
*
|
|
1827
|
+
* @example
|
|
1828
|
+
* ```typescript
|
|
1829
|
+
* // Remove all game-related listeners
|
|
1830
|
+
* const removed = bot.channel.offAll(['game']);
|
|
1831
|
+
* console.log(`Removed ${removed} game listeners`);
|
|
1832
|
+
*
|
|
1833
|
+
* // Remove all listeners for multiple tags
|
|
1834
|
+
* bot.channel.offAll(['game', 'moderation']);
|
|
1835
|
+
* ```
|
|
1836
|
+
*/
|
|
1837
|
+
offAll(tags: string | string[]): number;
|
|
1838
|
+
|
|
1839
|
+
/**
|
|
1840
|
+
* Query historical channel messages
|
|
1841
|
+
* Searches through stored messages (max 500 most recent)
|
|
1842
|
+
*
|
|
1843
|
+
* @param filter - Query filter criteria
|
|
1844
|
+
* @returns Array of matching messages, newest first
|
|
1845
|
+
*
|
|
1846
|
+
* @example
|
|
1847
|
+
* ```typescript
|
|
1848
|
+
* // Get all moderation messages from last hour
|
|
1849
|
+
* const modLogs = bot.channel.query({
|
|
1850
|
+
* tags: ['moderation'],
|
|
1851
|
+
* since: Date.now() - 3600000,
|
|
1852
|
+
* limit: 100
|
|
1853
|
+
* });
|
|
1854
|
+
*
|
|
1855
|
+
* // Get messages with multiple tags
|
|
1856
|
+
* const gameStarts = bot.channel.query({
|
|
1857
|
+
* tags: ['game', 'start'],
|
|
1858
|
+
* limit: 10
|
|
1859
|
+
* });
|
|
1860
|
+
*
|
|
1861
|
+
* // Get all messages from last 5 minutes
|
|
1862
|
+
* const recent = bot.channel.query({
|
|
1863
|
+
* since: Date.now() - 300000
|
|
1864
|
+
* });
|
|
1865
|
+
* ```
|
|
1866
|
+
*/
|
|
1867
|
+
query(filter?: ChannelFilter): ChannelMessage[];
|
|
1868
|
+
|
|
1869
|
+
/**
|
|
1870
|
+
* Get channel system statistics
|
|
1871
|
+
*
|
|
1872
|
+
* @returns Current channel statistics
|
|
1873
|
+
*
|
|
1874
|
+
* @example
|
|
1875
|
+
* ```typescript
|
|
1876
|
+
* const stats = bot.channel.stats();
|
|
1877
|
+
* console.log(`Messages stored: ${stats.totalMessages}`);
|
|
1878
|
+
* console.log(`Active listeners: ${stats.listeners}`);
|
|
1879
|
+
* ```
|
|
1880
|
+
*/
|
|
1881
|
+
stats(): ChannelStats;
|
|
1882
|
+
|
|
1883
|
+
/**
|
|
1884
|
+
* Clear all channel data
|
|
1885
|
+
* Removes message history and all listeners
|
|
1886
|
+
*
|
|
1887
|
+
* @example
|
|
1888
|
+
* ```typescript
|
|
1889
|
+
* // Reset channel system
|
|
1890
|
+
* bot.channel.clear();
|
|
1891
|
+
*
|
|
1892
|
+
* // Or on bot shutdown
|
|
1893
|
+
* process.on('SIGINT', () => {
|
|
1894
|
+
* bot.channel.clear();
|
|
1895
|
+
* bot.disconnect();
|
|
1896
|
+
* });
|
|
1897
|
+
* ```
|
|
1898
|
+
*/
|
|
1899
|
+
clear(): void;
|
|
1900
|
+
}
|
|
1901
|
+
|
|
1902
|
+
declare class DanceFloor {
|
|
1903
|
+
|
|
1904
|
+
/**
|
|
1905
|
+
* Create a new dance floor
|
|
1906
|
+
* @param Id - Unique identifier
|
|
1907
|
+
* @param corners - 3D boundaries {x, y, z, x1, y1, z1}
|
|
1908
|
+
* @param emotes - Emote configuration (JSON file path, single emote object, or array of emotes)
|
|
1909
|
+
* @returns Promise<DanceFloorConfig>
|
|
1910
|
+
* @example
|
|
1911
|
+
*
|
|
1912
|
+
* let danceFloor = bot.utils.DanceFloor
|
|
1913
|
+
*
|
|
1914
|
+
* // From JSON file
|
|
1915
|
+
* await danceFloor.create('floor1', { x:0, y:0, z:0, x1:10, y1:5, z1:10}, './dance.json');
|
|
1916
|
+
*
|
|
1917
|
+
* // Single emote
|
|
1918
|
+
* await danceFloor.create('floor2', corners, { id: "dance", name: "Dance", duration: 3000 });
|
|
1919
|
+
*
|
|
1920
|
+
* // Array of emotes
|
|
1921
|
+
* await danceFloor.create('floor3', corners, [
|
|
1922
|
+
* { id: "dance", name: "Dance", duration: 3000 },
|
|
1923
|
+
* { id: "wave", name: "Wave", duration: 2000 }
|
|
1924
|
+
* ]);
|
|
1925
|
+
*/
|
|
1926
|
+
create(Id: string, corners: DanceFloorCorners, emotes: string | DanceEmote | DanceEmote[]): Promise<DanceFloorConfig>;
|
|
1927
|
+
|
|
1928
|
+
/**
|
|
1929
|
+
* Get dance floor information
|
|
1930
|
+
* @param Id - Dance floor identifier
|
|
1931
|
+
* @returns DanceFloorConfig or null if not found
|
|
1932
|
+
*/
|
|
1933
|
+
getInfo(Id: string): DanceFloorConfig | null;
|
|
1934
|
+
|
|
1935
|
+
/**
|
|
1936
|
+
* Hot-reload emote configuration for a specific dance floor
|
|
1937
|
+
* @param floorId - Dance floor identifier
|
|
1938
|
+
* @returns Promise<boolean> - Success status
|
|
1939
|
+
*/
|
|
1940
|
+
hotReload(floorId: string): Promise<boolean>;
|
|
1941
|
+
|
|
1942
|
+
/**
|
|
1943
|
+
* Reload all dance floors with file watchers
|
|
1944
|
+
* @returns Promise<Array<{floorId: string, success: boolean, error?: string}>>
|
|
1945
|
+
*/
|
|
1946
|
+
reloadAll(): Promise<Array<{ floorId: string, success: boolean, error?: string }>>;
|
|
1947
|
+
|
|
1948
|
+
/**
|
|
1949
|
+
* Update emotes for a dance floor (programmatically)
|
|
1950
|
+
* @param floorId - Dance floor identifier
|
|
1951
|
+
* @param newEmotes - New emote configuration
|
|
1952
|
+
* @returns Promise<boolean>
|
|
1953
|
+
*/
|
|
1954
|
+
updateEmotes(floorId: string, newEmotes: string | DanceEmote | DanceEmote[]): Promise<boolean>;
|
|
1955
|
+
|
|
1956
|
+
/**
|
|
1957
|
+
* Destroy all dance floors and cleanup
|
|
1958
|
+
*/
|
|
1959
|
+
destroy(): void;
|
|
1960
|
+
}
|
|
1961
|
+
|
|
1962
|
+
declare class AwaitClass {
|
|
1963
|
+
/**
|
|
1964
|
+
* Wait for chat messages that match the filter
|
|
1965
|
+
* @param filter - Filter function that receives (user, message)
|
|
1966
|
+
* @param timeout - Timeout in milliseconds
|
|
1967
|
+
* @param maxToCollect - Maximum number of messages to collect
|
|
1968
|
+
* @param uniqueUsers - If true, only collect one message per user (default: false)
|
|
1969
|
+
*
|
|
1970
|
+
* @returns Promise resolving to array of matching events, or empty array if timeout
|
|
1971
|
+
* @example
|
|
1972
|
+
* ```typescript
|
|
1973
|
+
* // Wait for a specific command from any user
|
|
1974
|
+
* const results = await bot.await.chat(
|
|
1975
|
+
* (user, message) => message === '!play',
|
|
1976
|
+
* 30000,
|
|
1977
|
+
* 1,
|
|
1978
|
+
* false
|
|
1979
|
+
* );
|
|
1980
|
+
* if (results.length > 0) {
|
|
1981
|
+
* const [[user, message]] = results;
|
|
1982
|
+
* await bot.message.send(`Welcome ${user.username} to the game!`);
|
|
1983
|
+
* }
|
|
1984
|
+
*
|
|
1985
|
+
* // Collect one vote per user (unique users only)
|
|
1986
|
+
* await bot.message.send("Vote for your favorite color: !red, !blue, or !green");
|
|
1987
|
+
* const votes = await bot.await.chat(
|
|
1988
|
+
* (user, message) => ['!red', '!blue', '!green'].includes(message),
|
|
1989
|
+
* 45000,
|
|
1990
|
+
* 50,
|
|
1991
|
+
* true // Each user can only vote once
|
|
1992
|
+
* );
|
|
1993
|
+
*
|
|
1994
|
+
* // Count votes - each user counted only once
|
|
1995
|
+
* const redVotes = votes.filter(([user, message]) => message === '!red').length;
|
|
1996
|
+
* const blueVotes = votes.filter(([user, message]) => message === '!blue').length;
|
|
1997
|
+
* await bot.message.send(`Results - Red: ${redVotes}, Blue: ${blueVotes}`);
|
|
1998
|
+
*
|
|
1999
|
+
* // Collect messages from 5 unique users
|
|
2000
|
+
* const responses = await bot.await.chat(
|
|
2001
|
+
* (user, message) => message.startsWith('!feedback'),
|
|
2002
|
+
* 60000,
|
|
2003
|
+
* 5,
|
|
2004
|
+
* true // One feedback per user
|
|
2005
|
+
* );
|
|
2006
|
+
* ```
|
|
2007
|
+
*/
|
|
2008
|
+
chat(filter?: ChatFilter, timeout?: number, maxToCollect?: number, uniqueUsers?: boolean): Promise<[User, string][] | []>;
|
|
2009
|
+
|
|
2010
|
+
/**
|
|
2011
|
+
* Wait for whisper messages that match the filter
|
|
2012
|
+
* @param filter - Filter function that receives (user, message)
|
|
2013
|
+
* @param timeout - Timeout in milliseconds
|
|
2014
|
+
* @param maxToCollect - Maximum number of whispers to collect
|
|
2015
|
+
* @param uniqueUsers - If true, only collect one whisper per user (default: false)
|
|
2016
|
+
* @returns Promise resolving to array of matching events, or empty array if timeout
|
|
2017
|
+
* @example
|
|
2018
|
+
* ```typescript
|
|
2019
|
+
* // Secret command system - one request per user
|
|
2020
|
+
* await bot.message.send("Whisper me '!secret' for special access");
|
|
2021
|
+
* const secretRequests = await bot.await.whisper(
|
|
2022
|
+
* (user, message) => message === '!secret',
|
|
2023
|
+
* 30000,
|
|
2024
|
+
* 20,
|
|
2025
|
+
* true // Each user can only request once
|
|
2026
|
+
* );
|
|
2027
|
+
*
|
|
2028
|
+
* // Grant access to each unique user who whispered
|
|
2029
|
+
* for (const [user, message] of secretRequests) {
|
|
2030
|
+
* await bot.whisper.send(user.id, "You now have secret access! Use !commands");
|
|
2031
|
+
* await bot.room.privilege.add(user.id);
|
|
2032
|
+
* }
|
|
2033
|
+
*
|
|
2034
|
+
* // Private moderation reports - one report per user
|
|
2035
|
+
* const reports = await bot.await.whisper(
|
|
2036
|
+
* (user, message) => message.startsWith('!report'),
|
|
2037
|
+
* 60000,
|
|
2038
|
+
* 10,
|
|
2039
|
+
* true // Prevent users from spamming multiple reports
|
|
2040
|
+
* );
|
|
2041
|
+
*
|
|
2042
|
+
* // Each user's first report only
|
|
2043
|
+
* reports.forEach(([user, message]) => {
|
|
2044
|
+
* bot.utils.logger.info('Moderation', `Report from ${user.username}: ${message}`);
|
|
2045
|
+
* });
|
|
2046
|
+
* ```
|
|
2047
|
+
*/
|
|
2048
|
+
whisper(filter?: WhisperFilter, timeout?: number, maxToCollect?: number, uniqueUsers?: boolean): Promise<[User, string][] | []>;
|
|
2049
|
+
|
|
2050
|
+
/**
|
|
2051
|
+
* Wait for direct messages that match the filter
|
|
2052
|
+
* @param filter - Filter function that receives (user, message, conversation)
|
|
2053
|
+
* @param timeout - Timeout in milliseconds
|
|
2054
|
+
* @param maxToCollect - Maximum number of DMs to collect
|
|
2055
|
+
* @param uniqueUsers - If true, only collect one DM per user (default: false)
|
|
2056
|
+
* @returns Promise resolving to array of matching events, or empty array if timeout
|
|
2057
|
+
* @example
|
|
2058
|
+
* ```typescript
|
|
2059
|
+
* // Handle support tickets - one ticket per user
|
|
2060
|
+
* const supportTickets = await bot.await.direct(
|
|
2061
|
+
* (user, message, conversation) => message.includes('support') || message.includes('help'),
|
|
2062
|
+
* 120000,
|
|
2063
|
+
* 10,
|
|
2064
|
+
* true // One support request per user
|
|
2065
|
+
* );
|
|
2066
|
+
*
|
|
2067
|
+
* // Each user gets one ticket created
|
|
2068
|
+
* for (const [user, message, conversation] of supportTickets) {
|
|
2069
|
+
* await bot.direct.send(conversation.id, "Thanks for contacting support! We'll help you shortly.");
|
|
2070
|
+
* createSupportTicket(user.id, message, conversation.id);
|
|
2071
|
+
* }
|
|
2072
|
+
*
|
|
2073
|
+
* // Wait for confirmation from unique users
|
|
2074
|
+
* const confirmations = await bot.await.direct(
|
|
2075
|
+
* (user, message, conversation) =>
|
|
2076
|
+
* conversation.id === specificConversationId && message === '!confirm',
|
|
2077
|
+
* 60000,
|
|
2078
|
+
* 5,
|
|
2079
|
+
* true // One confirmation per user
|
|
2080
|
+
* );
|
|
2081
|
+
*
|
|
2082
|
+
* // Collect feedback from 10 unique users
|
|
2083
|
+
* await bot.direct.send(conversationId, "Please rate your experience 1-5 stars");
|
|
2084
|
+
* const ratings = await bot.await.direct(
|
|
2085
|
+
* (user, message, conv) => /^[1-5]$/.test(message) && conv.id === conversationId,
|
|
2086
|
+
* 30000,
|
|
2087
|
+
* 10,
|
|
2088
|
+
* true // One rating per user
|
|
2089
|
+
* );
|
|
2090
|
+
*
|
|
2091
|
+
* // Average rating from unique users only
|
|
2092
|
+
* const averageRating = ratings.reduce((sum, [user, rating]) => sum + parseInt(rating), 0) / ratings.length;
|
|
2093
|
+
* ```
|
|
2094
|
+
*/
|
|
2095
|
+
direct(filter?: DirectFilter, timeout?: number, maxToCollect?: number, uniqueUsers?: boolean): Promise<[User, string, Conversation][] | []>;
|
|
2096
|
+
|
|
2097
|
+
/**
|
|
2098
|
+
* Wait for tips that match the filter
|
|
2099
|
+
* @param filter - Filter function that receives (sender, receiver, currency)
|
|
2100
|
+
* @param timeout - Timeout in milliseconds
|
|
2101
|
+
* @param maxToCollect - Maximum number of tips to collect
|
|
2102
|
+
* @param uniqueUsers - If true, only count one tip per sender (default: false)
|
|
2103
|
+
* @returns Promise resolving to array of matching events, or empty array if timeout
|
|
2104
|
+
* @example
|
|
2105
|
+
* ```typescript
|
|
2106
|
+
* // Track first donation from each user
|
|
2107
|
+
* await bot.message.send("Fundraiser started! First donation from each user counts!");
|
|
2108
|
+
* const firstDonations = await bot.await.tip(
|
|
2109
|
+
* (sender, receiver, currency) =>
|
|
2110
|
+
* receiver.id === bot.info.user.id && currency.amount >= 50,
|
|
2111
|
+
* 300000,
|
|
2112
|
+
* 100,
|
|
2113
|
+
* true // Only count first donation from each user
|
|
2114
|
+
* );
|
|
2115
|
+
*
|
|
2116
|
+
* // Count unique donors, not total donations
|
|
2117
|
+
* const uniqueDonors = firstDonations.length;
|
|
2118
|
+
* let totalRaised = firstDonations.reduce((sum, [sender, receiver, currency]) => sum + currency.amount, 0);
|
|
2119
|
+
* await bot.message.send(`${uniqueDonors} unique donors raised ${totalRaised} gold!`);
|
|
2120
|
+
*
|
|
2121
|
+
* // VIP reward - first large donation only
|
|
2122
|
+
* const vipDonors = await bot.await.tip(
|
|
2123
|
+
* (sender, receiver, currency) =>
|
|
2124
|
+
* receiver.id === bot.info.user.id && currency.amount >= 500,
|
|
2125
|
+
* 180000,
|
|
2126
|
+
* 20,
|
|
2127
|
+
* true // Users can only become VIP once
|
|
2128
|
+
* );
|
|
2129
|
+
*
|
|
2130
|
+
* // Grant VIP to first-time large donors
|
|
2131
|
+
* vipDonors.forEach(([sender, receiver, currency]) => {
|
|
2132
|
+
* await bot.whisper.send(sender.id, "You're now a VIP! Special perks unlocked.");
|
|
2133
|
+
* await bot.room.privilege.add(sender.id);
|
|
2134
|
+
* });
|
|
2135
|
+
*
|
|
2136
|
+
* // Track unique tippers for analytics
|
|
2137
|
+
* const uniqueTippers = await bot.await.tip(
|
|
2138
|
+
* (sender, receiver, currency) => receiver.id === bot.info.user.id,
|
|
2139
|
+
* 60000,
|
|
2140
|
+
* 50,
|
|
2141
|
+
* true // Count each tipper only once
|
|
2142
|
+
* );
|
|
2143
|
+
*
|
|
2144
|
+
* bot.utils.logger.info('Economy', `${uniqueTippers.length} unique tippers in the last minute`);
|
|
2145
|
+
* ```
|
|
2146
|
+
*/
|
|
2147
|
+
tip(filter?: TipFilter, timeout?: number, maxToCollect?: number, uniqueUsers?: boolean): Promise<[Sender, Receiver, Currency][] | []>;
|
|
2148
|
+
|
|
2149
|
+
/**
|
|
2150
|
+
* Wait for player movements that match the filter
|
|
2151
|
+
* @param filter - Filter function that receives (user, position, anchor)
|
|
2152
|
+
* @param timeout - Timeout in milliseconds
|
|
2153
|
+
* @param maxToCollect - Maximum number of movements to collect
|
|
2154
|
+
* @param uniqueUsers - If true, only collect one movement per user (default: false)
|
|
2155
|
+
* @returns Promise resolving to array of matching events, or empty array if timeout
|
|
2156
|
+
* @example
|
|
2157
|
+
* ```typescript
|
|
2158
|
+
* // Track first entry to dance floor per user
|
|
2159
|
+
* const firstEntrants = await bot.await.movement(
|
|
2160
|
+
* (user, position, anchor) =>
|
|
2161
|
+
* position.x >= 10 && position.x <= 15 &&
|
|
2162
|
+
* position.z >= 10 && position.z <= 15,
|
|
2163
|
+
* 60000,
|
|
2164
|
+
* 30,
|
|
2165
|
+
* true // Only track first time each user enters
|
|
2166
|
+
* );
|
|
2167
|
+
*
|
|
2168
|
+
* // Welcome users on their first entry only
|
|
2169
|
+
* for (const [user, position, anchor] of firstEntrants) {
|
|
2170
|
+
* await bot.message.send(`Welcome to the dance floor, ${user.username}! First time here?`);
|
|
2171
|
+
* await bot.player.emote('dance', user.id);
|
|
2172
|
+
* }
|
|
2173
|
+
*
|
|
2174
|
+
* // Track unique users sitting on premium chairs
|
|
2175
|
+
* const uniqueChairUsers = await bot.await.movement(
|
|
2176
|
+
* (user, position, anchor) =>
|
|
2177
|
+
* anchor?.entity_id === 'premium_chair_001',
|
|
2178
|
+
* 120000,
|
|
2179
|
+
* 10,
|
|
2180
|
+
* true // Track each user only once
|
|
2181
|
+
* );
|
|
2182
|
+
*
|
|
2183
|
+
* // VIP area entry - track first visit per user
|
|
2184
|
+
* const firstVIPVisitors = await bot.await.movement(
|
|
2185
|
+
* (user, position, anchor) =>
|
|
2186
|
+
* position.y >= 5 && // Upper floor
|
|
2187
|
+
* position.x >= 20 && position.x <= 25 &&
|
|
2188
|
+
* position.z >= 20 && position.z <= 25,
|
|
2189
|
+
* 180000,
|
|
2190
|
+
* 50,
|
|
2191
|
+
* true // First visit only
|
|
2192
|
+
* );
|
|
2193
|
+
*
|
|
2194
|
+
* // Award achievement for first time leaving spawn
|
|
2195
|
+
* const spawnLeavers = await bot.await.movement(
|
|
2196
|
+
* (user, position, anchor) => {
|
|
2197
|
+
* const distanceFromSpawn = Math.sqrt(position.x ** 2 + position.z ** 2);
|
|
2198
|
+
* return distanceFromSpawn > 10;
|
|
2199
|
+
* },
|
|
2200
|
+
* 60000,
|
|
2201
|
+
* 100,
|
|
2202
|
+
* true // Achievement only once per user
|
|
2203
|
+
* );
|
|
2204
|
+
*
|
|
2205
|
+
* // Secret room discovery - once per user
|
|
2206
|
+
* const secretDiscoverers = await bot.await.movement(
|
|
2207
|
+
* (user, position, anchor) =>
|
|
2208
|
+
* position.x === 100 && position.y === 5 && position.z === 100,
|
|
2209
|
+
* 300000,
|
|
2210
|
+
* 50,
|
|
2211
|
+
* true // Reward only on first discovery
|
|
2212
|
+
* );
|
|
2213
|
+
*
|
|
2214
|
+
* secretDiscoverers.forEach(([user, position, anchor]) => {
|
|
2215
|
+
* await bot.whisper.send(user.id, "You found the secret room! Here's your reward.");
|
|
2216
|
+
* await bot.player.tip(user.id, 100);
|
|
2217
|
+
* });
|
|
2218
|
+
*
|
|
2219
|
+
* // Zone crossing - track first time per user
|
|
2220
|
+
* const firstZoneCrossers = await bot.await.movement(
|
|
2221
|
+
* (user, position, anchor) => {
|
|
2222
|
+
* const previousPosition = bot.cache.position.get(user.id)?.position;
|
|
2223
|
+
* if (!previousPosition) return false;
|
|
2224
|
+
*
|
|
2225
|
+
* const wasInZoneA = previousPosition.x < 0;
|
|
2226
|
+
* const nowInZoneB = position.x >= 0;
|
|
2227
|
+
* return wasInZoneA && nowInZoneB;
|
|
2228
|
+
* },
|
|
2229
|
+
* 120000,
|
|
2230
|
+
* 30,
|
|
2231
|
+
* true // Only count first crossing per user
|
|
2232
|
+
* );
|
|
2233
|
+
* ```
|
|
2234
|
+
*/
|
|
2235
|
+
movement(filter?: MovementFilter, timeout?: number, maxToCollect?: number, uniqueUsers?: boolean): Promise<[User, Position, AnchorPosition | null][] | []>;
|
|
2236
|
+
}
|
|
2237
|
+
|
|
2238
|
+
declare class WebApi {
|
|
2239
|
+
user: {
|
|
2240
|
+
/**
|
|
2241
|
+
* Get user information from Highrise Web API
|
|
2242
|
+
* @param identifier - User ID or username
|
|
2243
|
+
* @returns Promise resolving to formatted user data or null if not found
|
|
2244
|
+
* @throws {TypeError} If identifier is not a non-empty string
|
|
2245
|
+
* @example
|
|
2246
|
+
* ```typescript
|
|
2247
|
+
* const user = await bot.webapi.user.get('Unfairly');
|
|
2248
|
+
* ```
|
|
2249
|
+
*/
|
|
2250
|
+
get(identifier: string): Promise<WebApiUser | null>;
|
|
2251
|
+
|
|
2252
|
+
/**
|
|
2253
|
+
* Get user avatar as png in high quality
|
|
2254
|
+
* @param identifier - User ID or username
|
|
2255
|
+
* @param imagePath - User Avatar output path (default: "avatar.png")
|
|
2256
|
+
* @returns Promise resolving to getUserAvatarResponse if success or null if not
|
|
2257
|
+
* @throws {TypeError} If identifier is not a non-empty string
|
|
2258
|
+
*
|
|
2259
|
+
* @todo use username for imagePath -> "username".png
|
|
2260
|
+
*
|
|
2261
|
+
* @example
|
|
2262
|
+
* ```typescript
|
|
2263
|
+
* await bot.webapi.user.get('Unfairly', `${user.username}.png`);
|
|
2264
|
+
* ```
|
|
2265
|
+
*/
|
|
2266
|
+
getUserAvatar(identifier: string, imagePath: string): Promise<getUserAvatarResponse>
|
|
2267
|
+
}
|
|
2268
|
+
|
|
2269
|
+
room: {
|
|
2270
|
+
/**
|
|
2271
|
+
* Get detailed room information from Highrise Web API
|
|
2272
|
+
* @param roomId - Room ID to lookup
|
|
2273
|
+
* @returns Promise resolving to detailed room data or null if not found
|
|
2274
|
+
* @throws {TypeError} If roomId is not a non-empty string
|
|
2275
|
+
* @example
|
|
2276
|
+
* ```typescript
|
|
2277
|
+
* const room = await bot.webapi.room.get('692125c2521b7580234d0f35');
|
|
2278
|
+
* ```
|
|
2279
|
+
*/
|
|
2280
|
+
get(roomId: string): Promise<DetailedRoom | null>;
|
|
2281
|
+
|
|
2282
|
+
/**
|
|
2283
|
+
* Get a list of rooms from Highrise Web API with pagination
|
|
2284
|
+
* @param params - Query parameters for filtering and pagination
|
|
2285
|
+
* @returns Promise resolving to rooms list with pagination info or null
|
|
2286
|
+
* @throws {TypeError} If params are invalid
|
|
2287
|
+
* @example
|
|
2288
|
+
* ```typescript
|
|
2289
|
+
* // Get recent rooms
|
|
2290
|
+
* const rooms = await bot.webapi.room.list({ limit: 50, sort_order: 'desc' });
|
|
2291
|
+
*
|
|
2292
|
+
* // Search rooms by name
|
|
2293
|
+
* const results = await bot.webapi.room.list({ room_name: 'party', limit: 20 });
|
|
2294
|
+
*
|
|
2295
|
+
* // Get rooms by owner
|
|
2296
|
+
* const ownerRooms = await bot.webapi.room.list({ owner_id: '68a7dd5eecae68acca580f41' });
|
|
2297
|
+
*
|
|
2298
|
+
* // Pagination example
|
|
2299
|
+
* const page1 = await bot.webapi.room.list({ limit: 50 });
|
|
2300
|
+
* const page2 = await bot.webapi.room.list({ limit: 50, starts_after: page1.pagination.lastId });
|
|
2301
|
+
* ```
|
|
2302
|
+
*/
|
|
2303
|
+
list(params?: RoomsParams): Promise<RoomsListResponse | null>;
|
|
2304
|
+
|
|
2305
|
+
/**
|
|
2306
|
+
* Get bot current room details
|
|
2307
|
+
*/
|
|
2308
|
+
getCurrentRoom(): Promise<DetailedRoom>
|
|
2309
|
+
|
|
2310
|
+
/**
|
|
2311
|
+
* Search rooms by name (convenience method)
|
|
2312
|
+
* @param name - Room name to search for
|
|
2313
|
+
* @param limit - Maximum number of results (default: 20, max: 100)
|
|
2314
|
+
* @returns Promise resolving to rooms list or null
|
|
2315
|
+
* @example
|
|
2316
|
+
* ```typescript
|
|
2317
|
+
* const results = await bot.webapi.room.searchByName('party', 15);
|
|
2318
|
+
* ```
|
|
2319
|
+
*/
|
|
2320
|
+
searchByName(name: string, limit?: number): Promise<RoomsListResponse | null>;
|
|
2321
|
+
|
|
2322
|
+
/**
|
|
2323
|
+
* Get rooms by owner ID (convenience method)
|
|
2324
|
+
* @param ownerId - Owner user ID
|
|
2325
|
+
* @param limit - Maximum number of results (default: 20, max: 100)
|
|
2326
|
+
* @returns Promise resolving to rooms list or null
|
|
2327
|
+
* @example
|
|
2328
|
+
* ```typescript
|
|
2329
|
+
* const ownerRooms = await bot.webapi.room.getByOwner('68a7dd5eecae68acca580f41');
|
|
2330
|
+
* ```
|
|
2331
|
+
*/
|
|
2332
|
+
getByOwner(ownerId: string, limit?: number): Promise<RoomsListResponse | null>;
|
|
2333
|
+
|
|
2334
|
+
/**
|
|
2335
|
+
* Get recent rooms (convenience method)
|
|
2336
|
+
* @param limit - Maximum number of results (default: 20, max: 100)
|
|
2337
|
+
* @returns Promise resolving to rooms list or null
|
|
2338
|
+
* @example
|
|
2339
|
+
* ```typescript
|
|
2340
|
+
* const recent = await bot.webapi.room.getRecent(10);
|
|
2341
|
+
* ```
|
|
2342
|
+
*/
|
|
2343
|
+
getRecent(limit?: number): Promise<RoomsListResponse | null>;
|
|
2344
|
+
}
|
|
2345
|
+
|
|
2346
|
+
post: {
|
|
2347
|
+
/**
|
|
2348
|
+
* Get post information from Highrise Web API
|
|
2349
|
+
* @param postId - Post ID to lookup
|
|
2350
|
+
* @returns Promise resolving to formatted post data or null if not found
|
|
2351
|
+
* @throws {TypeError} If postId is not a non-empty string
|
|
2352
|
+
* @example
|
|
2353
|
+
* ```typescript
|
|
2354
|
+
* const post = await bot.webapi.post.get('post_123456');
|
|
2355
|
+
* ```
|
|
2356
|
+
*/
|
|
2357
|
+
get(postId: string): Promise<Post | null>;
|
|
2358
|
+
|
|
2359
|
+
/**
|
|
2360
|
+
* Get a list of posts with basic information (optimized for listing)
|
|
2361
|
+
* @param params - Query parameters for filtering and pagination
|
|
2362
|
+
* @returns Promise resolving to posts list with pagination info or null
|
|
2363
|
+
* @example
|
|
2364
|
+
* ```typescript
|
|
2365
|
+
* const posts = await bot.webapi.post.list({ limit: 50 });
|
|
2366
|
+
* posts.posts.forEach(post => {
|
|
2367
|
+
* console.log(`${post.id}: ${post.content.text.substring(0, 50)}...`);
|
|
2368
|
+
* console.log(`Likes: ${post.stats.likes}, Items: ${post.inventoryPreview?.itemCount}`);
|
|
2369
|
+
* });
|
|
2370
|
+
* ```
|
|
2371
|
+
*/
|
|
2372
|
+
list(params?: PostsParams): Promise<PostsListResponse | null>;
|
|
2373
|
+
|
|
2374
|
+
/**
|
|
2375
|
+
* Get posts by specific author (convenience method)
|
|
2376
|
+
* @param authorId - Author user ID
|
|
2377
|
+
* @param limit - Maximum number of results (default: 20, max: 100)
|
|
2378
|
+
* @returns Promise resolving to posts list or null
|
|
2379
|
+
* @example
|
|
2380
|
+
* ```typescript
|
|
2381
|
+
* const authorPosts = await bot.webapi.post.getByAuthor('68a7dd5eecae68acca580f41');
|
|
2382
|
+
* ```
|
|
2383
|
+
*/
|
|
2384
|
+
getByAuthor(authorId: string, limit?: number): Promise<PostsListResponse | null>;
|
|
2385
|
+
|
|
2386
|
+
/**
|
|
2387
|
+
* Get recent posts (convenience method)
|
|
2388
|
+
* @param limit - Maximum number of results (default: 20, max: 100)
|
|
2389
|
+
* @returns Promise resolving to posts list or null
|
|
2390
|
+
* @example
|
|
2391
|
+
* ```typescript
|
|
2392
|
+
* const recent = await bot.webapi.post.getRecent(10);
|
|
2393
|
+
* ```
|
|
2394
|
+
*/
|
|
2395
|
+
getRecent(limit?: number): Promise<PostsListResponse | null>;
|
|
2396
|
+
}
|
|
2397
|
+
|
|
2398
|
+
item: {
|
|
2399
|
+
/**
|
|
2400
|
+
* Get detailed item information from Highrise Web API
|
|
2401
|
+
* @param itemId - Item ID to lookup
|
|
2402
|
+
* @returns Promise resolving to detailed item data or null if not found
|
|
2403
|
+
* @throws {TypeError} If itemId is not a non-empty string
|
|
2404
|
+
* @example
|
|
2405
|
+
* ```typescript
|
|
2406
|
+
* const item = await bot.webapi.item.get('eye-n_fierycreatureeyes');
|
|
2407
|
+
*
|
|
2408
|
+
* // Example response includes:
|
|
2409
|
+
* // - Basic item info and pricing
|
|
2410
|
+
* // - Acquisition details
|
|
2411
|
+
* // - Skin parts and customization
|
|
2412
|
+
* // - Related items and affiliations
|
|
2413
|
+
* // - Storefront listings with sellers
|
|
2414
|
+
* // - Seller outfits and availability
|
|
2415
|
+
* ```
|
|
2416
|
+
*/
|
|
2417
|
+
get(itemId: string): Promise<ItemDetail | null>;
|
|
2418
|
+
|
|
2419
|
+
/**
|
|
2420
|
+
* Get a list of items from Highrise catalog with filtering and pagination
|
|
2421
|
+
* @param params - Query parameters for filtering and pagination
|
|
2422
|
+
* @returns Promise resolving to items list with pagination info or null
|
|
2423
|
+
* @throws {TypeError} If params are invalid
|
|
2424
|
+
* @example
|
|
2425
|
+
* ```typescript
|
|
2426
|
+
* // Get recent items
|
|
2427
|
+
* const items = await bot.webapi.item.list({ limit: 50, sort_order: 'desc' });
|
|
2428
|
+
*
|
|
2429
|
+
* // Get rare shirts
|
|
2430
|
+
* const rareShirts = await bot.webapi.item.list({
|
|
2431
|
+
* category: ItemCategory.SHIRT,
|
|
2432
|
+
* rarity: Rarity.RARE,
|
|
2433
|
+
* limit: 20
|
|
2434
|
+
* });
|
|
2435
|
+
*
|
|
2436
|
+
* // Search for dragon items
|
|
2437
|
+
* const dragonItems = await bot.webapi.item.list({ item_name: 'dragon', limit: 30 });
|
|
2438
|
+
*
|
|
2439
|
+
* // Pagination example
|
|
2440
|
+
* const page1 = await bot.webapi.item.list({ limit: 50 });
|
|
2441
|
+
* const page2 = await bot.webapi.item.list({ limit: 50, starts_after: page1.pagination.lastId });
|
|
2442
|
+
* ```
|
|
2443
|
+
*/
|
|
2444
|
+
list(params?: ItemsParams): Promise<ItemsListResponse | null>;
|
|
2445
|
+
|
|
2446
|
+
/**
|
|
2447
|
+
* Search for items in the Highrise catalog
|
|
2448
|
+
* @param params - Search parameters including query and pagination
|
|
2449
|
+
* @returns Promise resolving to items search results with pagination
|
|
2450
|
+
* @throws {TypeError} If params are invalid
|
|
2451
|
+
* @example
|
|
2452
|
+
* ```typescript
|
|
2453
|
+
* // Search for shirts
|
|
2454
|
+
* const shirts = await bot.webapi.item.search({ query: 'shirt', limit: 20 });
|
|
2455
|
+
*
|
|
2456
|
+
* // Paginate results
|
|
2457
|
+
* const page1 = await bot.webapi.item.search({ query: 'hat', limit: 20, skip: 0 });
|
|
2458
|
+
* const page2 = await bot.webapi.item.search({ query: 'hat', limit: 20, skip: 20 });
|
|
2459
|
+
*
|
|
2460
|
+
* // Process results
|
|
2461
|
+
* shirts.items.forEach(item => {
|
|
2462
|
+
* console.log(`${item.name} - ${item.pricing.gems} gems`);
|
|
2463
|
+
* console.log(`Purchasable: ${item.properties.isPurchasable}`);
|
|
2464
|
+
* console.log(`Tradable: ${item.properties.isTradable}`);
|
|
2465
|
+
* });
|
|
2466
|
+
* ```
|
|
2467
|
+
*/
|
|
2468
|
+
search(params?: ItemsSearchParams): Promise<ItemsSearchResponse | null>;
|
|
2469
|
+
|
|
2470
|
+
/**
|
|
2471
|
+
* Search items by name (convenience method)
|
|
2472
|
+
* @param name - Item name to search for
|
|
2473
|
+
* @param limit - Maximum number of results (default: 20, max: 100)
|
|
2474
|
+
* @returns Promise resolving to items search results
|
|
2475
|
+
* @example
|
|
2476
|
+
* ```typescript
|
|
2477
|
+
* const hats = await bot.webapi.item.searchByName('hat', 30);
|
|
2478
|
+
* ```
|
|
2479
|
+
*/
|
|
2480
|
+
searchByName(name: string, limit?: number): Promise<ItemsSearchResponse | null>;
|
|
2481
|
+
|
|
2482
|
+
/**
|
|
2483
|
+
* Get items by category (convenience method)
|
|
2484
|
+
* @param category - Item category to filter by
|
|
2485
|
+
* @param limit - Maximum number of results (default: 20, max: 100)
|
|
2486
|
+
* @returns Promise resolving to items list or null
|
|
2487
|
+
* @example
|
|
2488
|
+
* ```typescript
|
|
2489
|
+
* const hats = await bot.webapi.item.getByCategory(ItemCategory.HAT, 30);
|
|
2490
|
+
* ```
|
|
2491
|
+
*/
|
|
2492
|
+
getByCategory(category: ItemCategory, limit?: number): Promise<ItemsListResponse | null>;
|
|
2493
|
+
|
|
2494
|
+
/**
|
|
2495
|
+
* Get items by rarity (convenience method)
|
|
2496
|
+
* @param rarity - Item rarity to filter by
|
|
2497
|
+
* @param limit - Maximum number of results (default: 20, max: 100)
|
|
2498
|
+
* @returns Promise resolving to items list or null
|
|
2499
|
+
* @example
|
|
2500
|
+
* ```typescript
|
|
2501
|
+
* const epicItems = await bot.webapi.item.getByRarity(Rarity.EPIC, 25);
|
|
2502
|
+
* ```
|
|
2503
|
+
*/
|
|
2504
|
+
getByRarity(rarity: Rarity, limit?: number): Promise<ItemsListResponse | null>;
|
|
2505
|
+
|
|
2506
|
+
/**
|
|
2507
|
+
* Get items by name (convenience method)
|
|
2508
|
+
* @param name - Item name to search for
|
|
2509
|
+
* @param limit - Maximum number of results (default: 20, max: 100)
|
|
2510
|
+
* @returns Promise resolving to items list or null
|
|
2511
|
+
* @example
|
|
2512
|
+
* ```typescript
|
|
2513
|
+
* const dragonItems = await bot.webapi.item.getByName('dragon', 20);
|
|
2514
|
+
* ```
|
|
2515
|
+
*/
|
|
2516
|
+
getByName(name: string, limit?: number): Promise<ItemsListResponse | null>;
|
|
2517
|
+
|
|
2518
|
+
/**
|
|
2519
|
+
* Get recent items (convenience method)
|
|
2520
|
+
* @param limit - Maximum number of results (default: 20, max: 100)
|
|
2521
|
+
* @returns Promise resolving to items list or null
|
|
2522
|
+
* @example
|
|
2523
|
+
* ```typescript
|
|
2524
|
+
* const recent = await bot.webapi.item.getRecent(15);
|
|
2525
|
+
* ```
|
|
2526
|
+
*/
|
|
2527
|
+
getRecent(limit?: number): Promise<ItemsListResponse | null>;
|
|
2528
|
+
|
|
2529
|
+
/**
|
|
2530
|
+
* Get purchasable items (convenience method)
|
|
2531
|
+
* @param query - Search query (optional)
|
|
2532
|
+
* @param limit - Maximum number of results (default: 20, max: 100)
|
|
2533
|
+
* @returns Promise resolving to purchasable items only
|
|
2534
|
+
* @example
|
|
2535
|
+
* ```typescript
|
|
2536
|
+
* const purchasableHats = await bot.webapi.item.getPurchasable('hat');
|
|
2537
|
+
* ```
|
|
2538
|
+
*/
|
|
2539
|
+
getPurchasable(query?: string, limit?: number): Promise<ItemsSearchResponse | null>;
|
|
2540
|
+
|
|
2541
|
+
/**
|
|
2542
|
+
* Get tradable items (convenience method)
|
|
2543
|
+
* @param query - Search query (optional)
|
|
2544
|
+
* @param limit - Maximum number of results (default: 20, max: 100)
|
|
2545
|
+
* @returns Promise resolving to tradable items only
|
|
2546
|
+
* @example
|
|
2547
|
+
* ```typescript
|
|
2548
|
+
* const tradableItems = await bot.webapi.item.getTradable('', 50);
|
|
2549
|
+
* ```
|
|
2550
|
+
*/
|
|
2551
|
+
getTradable(query?: string, limit?: number): Promise<ItemsSearchResponse | null>;
|
|
2552
|
+
|
|
2553
|
+
/**
|
|
2554
|
+
* Get purchasable items by category (convenience method)
|
|
2555
|
+
* @param category - Item category to filter by
|
|
2556
|
+
* @param limit - Maximum number of results (default: 20, max: 100)
|
|
2557
|
+
* @returns Promise resolving to purchasable items only
|
|
2558
|
+
* @example
|
|
2559
|
+
* ```typescript
|
|
2560
|
+
* const purchasableShirts = await bot.webapi.item.getPurchasableByCategory(ItemCategory.SHIRT);
|
|
2561
|
+
* ```
|
|
2562
|
+
*/
|
|
2563
|
+
getPurchasableByCategory(category: ItemCategory, limit?: number): Promise<ItemsListResponse | null>;
|
|
2564
|
+
|
|
2565
|
+
/**
|
|
2566
|
+
* Get tradable items by category (convenience method)
|
|
2567
|
+
* @param category - Item category to filter by
|
|
2568
|
+
* @param limit - Maximum number of results (default: 20, max: 100)
|
|
2569
|
+
* @returns Promise resolving to tradable items only
|
|
2570
|
+
* @example
|
|
2571
|
+
* ```typescript
|
|
2572
|
+
* const tradableHats = await bot.webapi.item.getTradableByCategory(ItemCategory.HAT);
|
|
2573
|
+
* ```
|
|
2574
|
+
*/
|
|
2575
|
+
getTradableByCategory(category: ItemCategory, limit?: number): Promise<ItemsListResponse | null>;
|
|
2576
|
+
}
|
|
2577
|
+
|
|
2578
|
+
grab: {
|
|
2579
|
+
/**
|
|
2580
|
+
* Get detailed grab information from Highrise Web API
|
|
2581
|
+
* @param grabId - Grab ID to lookup
|
|
2582
|
+
* @returns Promise resolving to detailed grab data or null if not found
|
|
2583
|
+
* @throws {TypeError} If grabId is not a non-empty string
|
|
2584
|
+
* @example
|
|
2585
|
+
* ```typescript
|
|
2586
|
+
* const grab = await bot.webapi.grab.get('grab_123456');
|
|
2587
|
+
*
|
|
2588
|
+
* // Example response includes:
|
|
2589
|
+
* // - Complete grab details with all rewards and costs
|
|
2590
|
+
* // - Kompu reward system data
|
|
2591
|
+
* // - Limited time offers
|
|
2592
|
+
* // - Progress-based rewards
|
|
2593
|
+
* // - Item metadata and NFI information
|
|
2594
|
+
*
|
|
2595
|
+
* console.log(`🎁 ${grab.title}`);
|
|
2596
|
+
* console.log(`📝 ${grab.description}`);
|
|
2597
|
+
* console.log(`🖼️ Banner: ${grab.bannerImgUrl}`);
|
|
2598
|
+
*
|
|
2599
|
+
* // Process rewards
|
|
2600
|
+
* grab.rewards.forEach(reward => {
|
|
2601
|
+
* console.log(`🎯 Reward: ${reward.amount}x ${reward.rewardId}`);
|
|
2602
|
+
* if (reward.itemId) console.log(` Item: ${reward.itemId}`);
|
|
2603
|
+
* console.log(` Bound: ${reward.accountBound}, Tradable: ${reward.isTradable}`);
|
|
2604
|
+
* });
|
|
2605
|
+
*
|
|
2606
|
+
* // Process costs
|
|
2607
|
+
* grab.costs.forEach(cost => {
|
|
2608
|
+
* console.log(`💰 Cost: ${cost.amount}x ${cost.rewardId}`);
|
|
2609
|
+
* });
|
|
2610
|
+
* ```
|
|
2611
|
+
*/
|
|
2612
|
+
get(grabId: string): Promise<Grab | null>;
|
|
2613
|
+
}
|
|
2614
|
+
}
|
|
2615
|
+
|
|
2616
|
+
|
|
2617
|
+
declare class MovementCache {
|
|
2618
|
+
/**
|
|
2619
|
+
* Get user data by either userId or username
|
|
2620
|
+
* Automatically detects identifier type
|
|
2621
|
+
*
|
|
2622
|
+
* @param identifier - User ID (e.g., '68a7dd5eecae68acca580f41') or username (e.g., 'Unfairly')
|
|
2623
|
+
* @returns Cached user data or null if not found
|
|
2624
|
+
*
|
|
2625
|
+
* @example
|
|
2626
|
+
* // Get user position by ID
|
|
2627
|
+
* const userData = bot.cache.position.get('68a7dd5eecae68acca580f41');
|
|
2628
|
+
*
|
|
2629
|
+
* // Get user position by username
|
|
2630
|
+
* const userData = bot.cache.position.get('Unfairly');
|
|
2631
|
+
*
|
|
2632
|
+
* // Check if user is in cache
|
|
2633
|
+
* const isCached = bot.cache.position.get(userId) !== null;
|
|
2634
|
+
*/
|
|
2635
|
+
get(identifier: string): CachedUser | null;
|
|
2636
|
+
|
|
2637
|
+
/**
|
|
2638
|
+
* Get all players within a square area centered at a point
|
|
2639
|
+
* @param center - Center point coordinates {x, y, z}
|
|
2640
|
+
* @param sideLength - Length of each side of the square
|
|
2641
|
+
* @returns Array of users with their positions and cache data
|
|
2642
|
+
* @example
|
|
2643
|
+
* ```typescript
|
|
2644
|
+
* // Get players in 8x8 square centered at (10, 0, 10)
|
|
2645
|
+
* const players = bot.cache.position.getPlayersInSquare(
|
|
2646
|
+
* { x: 10, y: 0, z: 10 },
|
|
2647
|
+
* 8
|
|
2648
|
+
* );
|
|
2649
|
+
*
|
|
2650
|
+
* players.forEach(player => {
|
|
2651
|
+
* console.log(`${player.user.username} at (${player.position.x}, ${player.position.z})`);
|
|
2652
|
+
* });
|
|
2653
|
+
* ```
|
|
2654
|
+
*/
|
|
2655
|
+
getPlayersInSquare(center: Position, sideLength: number): SpatialUser[];
|
|
2656
|
+
|
|
2657
|
+
/**
|
|
2658
|
+
* Get all players within a rectangular area defined by four corners
|
|
2659
|
+
* @param corners - Object containing four corner coordinates
|
|
2660
|
+
* @returns Array of users with their positions and cache data
|
|
2661
|
+
* @example
|
|
2662
|
+
* ```typescript
|
|
2663
|
+
* // Get players in 10x10 rectangle
|
|
2664
|
+
* const players = bot.cache.position.getPlayersInRectangle({
|
|
2665
|
+
* c1: { x: 5, z: 5 },
|
|
2666
|
+
* c2: { x: 15, z: 5 },
|
|
2667
|
+
* c3: { x: 15, z: 15 },
|
|
2668
|
+
* c4: { x: 5, z: 15 }
|
|
2669
|
+
* });
|
|
2670
|
+
*
|
|
2671
|
+
* // Check if specific user is in area
|
|
2672
|
+
* const targetUser = players.find(p => p.user.id === '68a7dd5eecae68acca580f41');
|
|
2673
|
+
* if (targetUser) {
|
|
2674
|
+
* await bot.message.send(`${targetUser.user.username} is in the designated area!`);
|
|
2675
|
+
* }
|
|
2676
|
+
* ```
|
|
2677
|
+
*/
|
|
2678
|
+
getPlayersInRectangle(corners: RectangleCorners): SpatialUser[];
|
|
2679
|
+
|
|
2680
|
+
/**
|
|
2681
|
+
* Get all players within a circular area
|
|
2682
|
+
* @param center - Center point coordinates {x, z}
|
|
2683
|
+
* @param radius - Radius of the circular area
|
|
2684
|
+
* @returns Array of users sorted by distance from center (closest first)
|
|
2685
|
+
* @example
|
|
2686
|
+
* ```typescript
|
|
2687
|
+
* // Get players within 5 units radius of center (10, 10)
|
|
2688
|
+
* const players = bot.cache.position.getPlayersInCircle(
|
|
2689
|
+
* { x: 10, z: 10 },
|
|
2690
|
+
* 5
|
|
2691
|
+
* );
|
|
2692
|
+
*
|
|
2693
|
+
* // Get the closest player to center
|
|
2694
|
+
* const closestPlayer = players[0];
|
|
2695
|
+
* if (closestPlayer) {
|
|
2696
|
+
* console.log(`Closest player: ${closestPlayer.user.username} (${closestPlayer.distance} units)`);
|
|
2697
|
+
* }
|
|
2698
|
+
*
|
|
2699
|
+
* // Filter players within specific distance
|
|
2700
|
+
* const nearbyPlayers = players.filter(p => p.distance <= 3);
|
|
2701
|
+
* ```
|
|
2702
|
+
*/
|
|
2703
|
+
getPlayersInCircle(center: { x: number; z: number }, radius: number): SpatialUserWithDistance[];
|
|
2704
|
+
|
|
2705
|
+
/**
|
|
2706
|
+
* Get players within a specific Y-level range (vertical filtering)
|
|
2707
|
+
* @param minY - Minimum Y coordinate
|
|
2708
|
+
* @param maxY - Maximum Y coordinate
|
|
2709
|
+
* @returns Array of users within the vertical range
|
|
2710
|
+
* @example
|
|
2711
|
+
* ```typescript
|
|
2712
|
+
* // Get players on ground level (Y between -1 and 1)
|
|
2713
|
+
* const groundPlayers = bot.cache.position.getPlayersInVerticalRange(-1, 1);
|
|
2714
|
+
*
|
|
2715
|
+
* // Get players on upper floors (Y > 5)
|
|
2716
|
+
* const upperFloorPlayers = bot.cache.position.getPlayersInVerticalRange(5, 50);
|
|
2717
|
+
* ```
|
|
2718
|
+
*/
|
|
2719
|
+
getPlayersInVerticalRange(minY: number, maxY: number): SpatialUser[];
|
|
2720
|
+
|
|
2721
|
+
/**
|
|
2722
|
+
* Get the closest player to a specified point
|
|
2723
|
+
* @param point - Reference point coordinates {x, z}
|
|
2724
|
+
* @returns The closest player or null if no players in cache
|
|
2725
|
+
* @example
|
|
2726
|
+
* ```typescript
|
|
2727
|
+
* // Find closest player to bot's position
|
|
2728
|
+
* const closest = bot.cache.position.getClosestPlayer({ x: 10, z: 10 });
|
|
2729
|
+
* if (closest) {
|
|
2730
|
+
* await bot.whisper.send(closest.user.id, `You're the closest player to me!`);
|
|
2731
|
+
* }
|
|
2732
|
+
* ```
|
|
2733
|
+
*/
|
|
2734
|
+
getClosestPlayer(point: { x: number; z: number }): SpatialUserWithDistance | null;
|
|
2735
|
+
|
|
2736
|
+
/**
|
|
2737
|
+
* Get players sorted by distance from a point
|
|
2738
|
+
* @param point - Reference point coordinates {x, z}
|
|
2739
|
+
* @param maxDistance - Optional maximum distance filter
|
|
2740
|
+
* @returns Array of players sorted by distance (closest first)
|
|
2741
|
+
* @example
|
|
2742
|
+
* ```typescript
|
|
2743
|
+
* // Get all players sorted by distance from spawn
|
|
2744
|
+
* const sortedPlayers = bot.cache.position.getPlayersByDistance(
|
|
2745
|
+
* { x: 0, z: 0 }
|
|
2746
|
+
* );
|
|
2747
|
+
*
|
|
2748
|
+
* // Get players within 10 units, sorted
|
|
2749
|
+
* const nearbyPlayers = bot.cache.position.getPlayersByDistance(
|
|
2750
|
+
* { x: 10, z: 10 },
|
|
2751
|
+
* 10
|
|
2752
|
+
* );
|
|
2753
|
+
* ```
|
|
2754
|
+
*/
|
|
2755
|
+
getPlayersByDistance(point: { x: number; z: number }, maxDistance?: number): SpatialUserWithDistance[];
|
|
2756
|
+
|
|
2757
|
+
/**
|
|
2758
|
+
* Check if a specific player is within a square area
|
|
2759
|
+
* @param userId - User ID to check
|
|
2760
|
+
* @param center - Center point of the square
|
|
2761
|
+
* @param sideLength - Side length of the square
|
|
2762
|
+
* @returns True if player is within the area
|
|
2763
|
+
* @example
|
|
2764
|
+
* ```typescript
|
|
2765
|
+
* // Check if specific user is in dance floor area
|
|
2766
|
+
* const isOnDanceFloor = bot.cache.position.isPlayerInSquare(
|
|
2767
|
+
* '68a7dd5eecae68acca580f41',
|
|
2768
|
+
* { x: 10, y: 0, z: 10 },
|
|
2769
|
+
* 8
|
|
2770
|
+
* );
|
|
2771
|
+
*
|
|
2772
|
+
* if (isOnDanceFloor) {
|
|
2773
|
+
* await bot.player.emote('68a7dd5eecae68acca580f41', 'dance');
|
|
2774
|
+
* }
|
|
2775
|
+
* ```
|
|
2776
|
+
*/
|
|
2777
|
+
isPlayerInSquare(userId: string, center: Position, sideLength: number): boolean;
|
|
2778
|
+
|
|
2779
|
+
/**
|
|
2780
|
+
* Check if a specific player is within a rectangular area
|
|
2781
|
+
* @param userId - User ID to check
|
|
2782
|
+
* @param corners - Rectangle corner coordinates
|
|
2783
|
+
* @returns True if player is within the area
|
|
2784
|
+
* @example
|
|
2785
|
+
* ```typescript
|
|
2786
|
+
* const isInVIPArea = bot.cache.position.isPlayerInRectangle(
|
|
2787
|
+
* '68a7dd5eecae68acca580f41',
|
|
2788
|
+
* {
|
|
2789
|
+
* c1: { x: 20, z: 20 },
|
|
2790
|
+
* c2: { x: 25, z: 20 },
|
|
2791
|
+
* c3: { x: 25, z: 25 },
|
|
2792
|
+
* c4: { x: 20, z: 25 }
|
|
2793
|
+
* }
|
|
2794
|
+
* );
|
|
2795
|
+
* ```
|
|
2796
|
+
*/
|
|
2797
|
+
isPlayerInRectangle(userId: string, corners: RectangleCorners): boolean;
|
|
2798
|
+
|
|
2799
|
+
/**
|
|
2800
|
+
* Get the number of players in a square area
|
|
2801
|
+
* @param center - Center point of the square
|
|
2802
|
+
* @param sideLength - Side length of the square
|
|
2803
|
+
* @returns Number of players in the area
|
|
2804
|
+
* @example
|
|
2805
|
+
* ```typescript
|
|
2806
|
+
* // Count players in spawn area
|
|
2807
|
+
* const playerCount = bot.cache.position.getPlayerCountInSquare(
|
|
2808
|
+
* { x: 0, y: 0, z: 0 },
|
|
2809
|
+
* 10
|
|
2810
|
+
* );
|
|
2811
|
+
* await bot.message.send(`There are ${playerCount} players at spawn!`);
|
|
2812
|
+
* ```
|
|
2813
|
+
*/
|
|
2814
|
+
getPlayerCountInSquare(center: Position, sideLength: number): number;
|
|
2815
|
+
|
|
2816
|
+
/**
|
|
2817
|
+
* Get the number of players in a rectangular area
|
|
2818
|
+
* @param corners - Rectangle corner coordinates
|
|
2819
|
+
* @returns Number of players in the area
|
|
2820
|
+
*/
|
|
2821
|
+
getPlayerCountInRectangle(corners: RectangleCorners): number;
|
|
2822
|
+
}
|
|
2823
|
+
|
|
2824
|
+
declare class InventoryClass {
|
|
2825
|
+
/**
|
|
2826
|
+
* Get the bot's inventory items
|
|
2827
|
+
* @returns Promise resolving to array of inventory items
|
|
2828
|
+
* @example
|
|
2829
|
+
* ```typescript
|
|
2830
|
+
* const items = await bot.inventory.get();
|
|
2831
|
+
* console.log(items);
|
|
2832
|
+
* ```
|
|
2833
|
+
*/
|
|
2834
|
+
get(): Promise<GetInventoryResponse[]>;
|
|
2835
|
+
|
|
2836
|
+
/**
|
|
2837
|
+
* Outfit management
|
|
2838
|
+
*/
|
|
2839
|
+
public outfit: {
|
|
2840
|
+
/**
|
|
2841
|
+
* Set the bot's outfit with specified items
|
|
2842
|
+
* @param outfit - Array of outfit items to wear (default: default skin)
|
|
2843
|
+
* @returns Promise resolving to operation success status
|
|
2844
|
+
* @example
|
|
2845
|
+
* ```typescript
|
|
2846
|
+
* // Set default outfit
|
|
2847
|
+
* await bot.inventory.outfit.set();
|
|
2848
|
+
*
|
|
2849
|
+
* // Set custom outfit
|
|
2850
|
+
* await bot.inventory.outfit.set([
|
|
2851
|
+
* {
|
|
2852
|
+
* type: 'clothing',
|
|
2853
|
+
* amount: 1,
|
|
2854
|
+
* id: 'shirt-n_cooltshirt',
|
|
2855
|
+
* account_bound: false,
|
|
2856
|
+
* active_palette: null
|
|
2857
|
+
* },
|
|
2858
|
+
* {
|
|
2859
|
+
* type: 'clothing',
|
|
2860
|
+
* amount: 1,
|
|
2861
|
+
* id: 'pants-n_jeans',
|
|
2862
|
+
* account_bound: false,
|
|
2863
|
+
* active_palette: null
|
|
2864
|
+
* }
|
|
2865
|
+
* ]);
|
|
2866
|
+
* ```
|
|
2867
|
+
*/
|
|
2868
|
+
set(outfit?: Array<Outfit>): Promise<boolean>;
|
|
2869
|
+
}
|
|
2870
|
+
|
|
2871
|
+
/**
|
|
2872
|
+
* Wallet management for the bot's economy
|
|
2873
|
+
*/
|
|
2874
|
+
public wallet: {
|
|
2875
|
+
/**
|
|
2876
|
+
* Get the bot's wallet information in a structured format
|
|
2877
|
+
* @returns Promise resolving to organized wallet data
|
|
2878
|
+
* @example
|
|
2879
|
+
* ```typescript
|
|
2880
|
+
* // access to specific currencies
|
|
2881
|
+
* const wallet = await bot.inventory.wallet.get();
|
|
2882
|
+
* console.log(`Gold: ${wallet.gold}`);
|
|
2883
|
+
* console.log(`Boost tokens: ${wallet.boost_tokens}`);
|
|
2884
|
+
* console.log(`Voice tokens: ${wallet.voice_tokens}`);
|
|
2885
|
+
*
|
|
2886
|
+
* // Use in economy checks
|
|
2887
|
+
* if (wallet.gold >= 100) {
|
|
2888
|
+
* await bot.player.tip('68a7dd5eecae68acca580f41', 100);
|
|
2889
|
+
* }
|
|
2890
|
+
* ```
|
|
2891
|
+
*/
|
|
2892
|
+
get(): Promise<WalletResponse>;
|
|
2893
|
+
}
|
|
2894
|
+
|
|
2895
|
+
public boost: {
|
|
2896
|
+
/**
|
|
2897
|
+
* Buy room boosts
|
|
2898
|
+
* @param payment_method - Payment method to use (default: 'bot_wallet_only')
|
|
2899
|
+
* @param amount - Number of boosts to buy (default: 1)
|
|
2900
|
+
* @returns Promise resolving to purchase result
|
|
2901
|
+
* @example
|
|
2902
|
+
* ```typescript
|
|
2903
|
+
* const result = await bot.inventory.boost.buy('bot_wallet_only', 1);
|
|
2904
|
+
* if (result === 'success') {
|
|
2905
|
+
* console.log('Boost purchased successfully');
|
|
2906
|
+
* }
|
|
2907
|
+
* ```
|
|
2908
|
+
*/
|
|
2909
|
+
buy(payment_method?: PaymentMethods, amount?: number): Promise<string>
|
|
2910
|
+
}
|
|
2911
|
+
|
|
2912
|
+
public voice: {
|
|
2913
|
+
/**
|
|
2914
|
+
* Buy room voice token
|
|
2915
|
+
* @param payment_method - Payment method to use (default: 'bot_wallet_only')
|
|
2916
|
+
* @param amount - Number of voice tokens to buy (default: 1)
|
|
2917
|
+
* @returns Promise resolving to purchase result
|
|
2918
|
+
* @example
|
|
2919
|
+
* ```typescript
|
|
2920
|
+
* const result = await bot.inventory.voice.buy('bot_wallet_only', 1);
|
|
2921
|
+
* if (result === 'success') {
|
|
2922
|
+
* console.log('Voice token purchased successfully');
|
|
2923
|
+
* }
|
|
2924
|
+
* ```
|
|
2925
|
+
*/
|
|
2926
|
+
buy(payment_method?: PaymentMethods): Promise<string>
|
|
2927
|
+
}
|
|
2928
|
+
|
|
2929
|
+
public item: {
|
|
2930
|
+
/**
|
|
2931
|
+
* Buy an item from the shop
|
|
2932
|
+
* @param item_id - The ID of the item to purchase
|
|
2933
|
+
* @returns Promise resolving to purchase result
|
|
2934
|
+
* @example
|
|
2935
|
+
* ```typescript
|
|
2936
|
+
* const result = await bot.shop.item.buy('item_123');
|
|
2937
|
+
* if (result === 'success') {
|
|
2938
|
+
* console.log('Item purchased successfully');
|
|
2939
|
+
* }
|
|
2940
|
+
* ```
|
|
2941
|
+
*/
|
|
2942
|
+
buy(item_id: string): Promise<string>
|
|
2943
|
+
}
|
|
2944
|
+
}
|
|
2945
|
+
|
|
2946
|
+
declare class MessageClass {
|
|
2947
|
+
/**
|
|
2948
|
+
* Send a message to the Highrise room (visible to all users in the room)
|
|
2949
|
+
* @param message - The message to send to the Highrise room
|
|
2950
|
+
* @throws {Error} If message is empty, too long, or contains invalid characters
|
|
2951
|
+
* @example
|
|
2952
|
+
* // Send a simple message
|
|
2953
|
+
* await bot.message.send("Hello everyone!");
|
|
2954
|
+
*
|
|
2955
|
+
* // Send a welcome message
|
|
2956
|
+
* await bot.message.send("Welcome to the room! 🎉");
|
|
2957
|
+
*
|
|
2958
|
+
* // Send a command announcement
|
|
2959
|
+
* await bot.message.send("Type !help for available commands");
|
|
2960
|
+
*/
|
|
2961
|
+
send(message: string): Promise<boolean>;
|
|
2962
|
+
}
|
|
2963
|
+
|
|
2964
|
+
declare class WhisperClass {
|
|
2965
|
+
/**
|
|
2966
|
+
* Send a private whisper message to a specific user in the Highrise room
|
|
2967
|
+
* @param user_id - The user ID to send the whisper to
|
|
2968
|
+
* @param message - The private message to send
|
|
2969
|
+
* @throws {Error} If user_id is invalid or message is empty/too long
|
|
2970
|
+
* @example
|
|
2971
|
+
* // Send a private notification
|
|
2972
|
+
* await bot.whisper.send("68a7dd5eecae68acca580f41", "Your item has been delivered! Check your inventory.");
|
|
2973
|
+
*/
|
|
2974
|
+
send(user_id: string, message: string): Promise<boolean>;
|
|
2975
|
+
}
|
|
2976
|
+
|
|
2977
|
+
|
|
2978
|
+
declare class DirectClass {
|
|
2979
|
+
|
|
2980
|
+
/**
|
|
2981
|
+
* Send a direct message to a specific user using the conversation_id
|
|
2982
|
+
* @param conversation_id - The conversation ID to send the message in
|
|
2983
|
+
* @param message - The direct message to send
|
|
2984
|
+
* @throws {Error} If conversation_id is invalid or message is empty/too long
|
|
2985
|
+
* @example
|
|
2986
|
+
* // Send a direct notification
|
|
2987
|
+
* await bot.direct.send("1_on_1:68a7dd5eecae68acca580f41:68a7dd5eecae68acca580f41", "Your item has been delivered! Check your inventory.");
|
|
2988
|
+
*/
|
|
2989
|
+
send(conversation_id: string, message: string): Promise<boolean>;
|
|
2990
|
+
|
|
2991
|
+
/**
|
|
2992
|
+
* Send a direct message to a specific user using array of ID
|
|
2993
|
+
* @param user_Ids - Array of IDs to send the message to
|
|
2994
|
+
* @param message - The direct message to send
|
|
2995
|
+
* @throws {Error} If user_Ids is not array or less than 0 or bigger than 100 or message is empty/too long
|
|
2996
|
+
* @example
|
|
2997
|
+
* // Send a bulk direct notification
|
|
2998
|
+
* await bot.direct.bulkSend(['692125c2521b7580234d0f35', '68a7dd5eecae68acca580f41'], "Your item has been delivered! Check your inventory.");
|
|
2999
|
+
*/
|
|
3000
|
+
bulkSend(user_Ids: string[], message: string): Promise<boolean>;
|
|
3001
|
+
|
|
3002
|
+
/**
|
|
3003
|
+
* Send a room or world invitation to a conversation
|
|
3004
|
+
* @param conversation_id - The conversation ID to send the invitation to
|
|
3005
|
+
* @param options - Invitation options (must provide exactly one of room_id or world_id)
|
|
3006
|
+
* @returns Promise resolving to operation success status
|
|
3007
|
+
* @throws {TypeError} If conversation_id is invalid or options don't contain exactly one valid option
|
|
3008
|
+
* @example
|
|
3009
|
+
* ```typescript
|
|
3010
|
+
* // Send room invitation
|
|
3011
|
+
* await bot.direct.invite('1_on_1:user1:user2', { room_id: '692125c2521b7580234d0f35' });
|
|
3012
|
+
*
|
|
3013
|
+
* // Send world invitation
|
|
3014
|
+
* await bot.direct.invite('1_on_1:user1:user2', { world_id: 'world_123456' });
|
|
3015
|
+
*
|
|
3016
|
+
* // This will throw an error (no options provided):
|
|
3017
|
+
* await bot.direct.invite('1_on_1:user1:user2', {});
|
|
3018
|
+
*
|
|
3019
|
+
* // This will throw an error (both options provided):
|
|
3020
|
+
* await bot.direct.invite('1_on_1:user1:user2', {
|
|
3021
|
+
* room_id: 'room_123',
|
|
3022
|
+
* world_id: 'world_456'
|
|
3023
|
+
* });
|
|
3024
|
+
* ```
|
|
3025
|
+
*/
|
|
3026
|
+
invite(conversation_id: string, options: InviteOptions): Promise<boolean>;
|
|
3027
|
+
|
|
3028
|
+
/**
|
|
3029
|
+
* Send a room or world invitation to a conversation
|
|
3030
|
+
* @param user_Ids - Array of IDs to send the invitation to
|
|
3031
|
+
* @param options - Invitation options (must provide exactly one of room_id or world_id)
|
|
3032
|
+
* @returns Promise resolving to operation success status
|
|
3033
|
+
* @throws {TypeError} If user_Ids is not array or less than 0 or bigger than 100 or options don't contain exactly one valid option
|
|
3034
|
+
* @example
|
|
3035
|
+
* ```typescript
|
|
3036
|
+
* // Send bulk room invitation
|
|
3037
|
+
* await bot.direct.bulkInvite(['692125c2521b7580234d0f35', '68a7dd5eecae68acca580f41'], { room_id: '692125c2521b7580234d0f35' });
|
|
3038
|
+
*
|
|
3039
|
+
* // Send bulk world invitation
|
|
3040
|
+
* await bot.direct.bulkInvite(['692125c2521b7580234d0f35', '68a7dd5eecae68acca580f41'], { world_id: 'world_123456' });
|
|
3041
|
+
*
|
|
3042
|
+
* // This will throw an error (no options provided):
|
|
3043
|
+
* await bot.direct.bulkInvite(['692125c2521b7580234d0f35', '68a7dd5eecae68acca580f41'], {});
|
|
3044
|
+
*
|
|
3045
|
+
* // This will throw an error (both options provided):
|
|
3046
|
+
* await bot.direct.bulkInvite(['692125c2521b7580234d0f35', '68a7dd5eecae68acca580f41'], {
|
|
3047
|
+
* room_id: 'room_123',
|
|
3048
|
+
* world_id: 'world_456'
|
|
3049
|
+
* });
|
|
3050
|
+
* ```
|
|
3051
|
+
*/
|
|
3052
|
+
bulkInvite(user_Ids: string[], options: InviteOptions): Promise<boolean>;
|
|
3053
|
+
|
|
3054
|
+
/**
|
|
3055
|
+
* Conversations management for direct messaging
|
|
3056
|
+
*/
|
|
3057
|
+
public conversations: {
|
|
3058
|
+
/**
|
|
3059
|
+
* Get the conversations of the bot
|
|
3060
|
+
* @param last_id - Last conversation in the list, used to get the next 20 conversations
|
|
3061
|
+
* @param not_joined - If true, only returns conversations that bot has not joined yet
|
|
3062
|
+
* @returns Array of conversation responses
|
|
3063
|
+
* @example
|
|
3064
|
+
* // Get first 20 conversations
|
|
3065
|
+
* const conversations = await bot.direct.conversations.get();
|
|
3066
|
+
*
|
|
3067
|
+
* // Get next 20 conversations using last_id
|
|
3068
|
+
* const nextConversations = await bot.direct.conversations.get(conversations[19].id);
|
|
3069
|
+
*
|
|
3070
|
+
* // Get only unjoined conversations
|
|
3071
|
+
* const unjoined = await bot.direct.conversations.get(undefined, true);
|
|
3072
|
+
*/
|
|
3073
|
+
get(last_id?: string, not_joined?: boolean): Promise<GetConversationsResponse[]>;
|
|
3074
|
+
|
|
3075
|
+
/**
|
|
3076
|
+
* Leave a conversation using conversation_id
|
|
3077
|
+
* @param conversation_id - Conversation id to leave from
|
|
3078
|
+
* @example
|
|
3079
|
+
* await bot.direct.conversations.leave('1_on_1:68a7dd5eecae68acca580f41:68a7dd5eecae68acca580f41');
|
|
3080
|
+
*/
|
|
3081
|
+
leave(conversation_id: string): Promise<boolean>;
|
|
3082
|
+
}
|
|
3083
|
+
|
|
3084
|
+
/**
|
|
3085
|
+
* Messages management within conversations
|
|
3086
|
+
*/
|
|
3087
|
+
public messages: {
|
|
3088
|
+
/**
|
|
3089
|
+
* Get the messages of a conversation
|
|
3090
|
+
* @param conversation_id - Conversation id to get the messages from
|
|
3091
|
+
* @param last_message_id - Last message id to get the next 20 messages
|
|
3092
|
+
* @returns Array of message responses
|
|
3093
|
+
* @example
|
|
3094
|
+
* // Get first 20 messages from a conversation
|
|
3095
|
+
* const messages = await bot.direct.messages.get('1_on_1:68a7dd5eecae68acca580f41:68a7dd5eecae68acca580f41');
|
|
3096
|
+
*
|
|
3097
|
+
* // Get next 20 messages using last_message_id
|
|
3098
|
+
* const nextMessages = await bot.direct.messages.get('1_on_1:68a7dd5eecae68acca580f41:68a7dd5eecae68acca580f41', messages[19].id);
|
|
3099
|
+
*/
|
|
3100
|
+
get(conversation_id: string, last_message_id?: string): Promise<GetMessagesResponse[]>;
|
|
3101
|
+
}
|
|
3102
|
+
}
|
|
3103
|
+
|
|
3104
|
+
declare class PlayerClass {
|
|
3105
|
+
|
|
3106
|
+
/**
|
|
3107
|
+
* Walk the player to specified coordinates with optional facing direction
|
|
3108
|
+
* @param x - The x coordinate to walk to
|
|
3109
|
+
* @param y - The y coordinate to walk to
|
|
3110
|
+
* @param z - The z coordinate to walk to
|
|
3111
|
+
* @param facing - The direction the player should face after walking (default: 'FrontRight')
|
|
3112
|
+
* @throws {TypeError} If any coordinate is missing or invalid types are provided
|
|
3113
|
+
* @example
|
|
3114
|
+
* await bot.player.walk(10, 5, 15, 'FrontLeft');
|
|
3115
|
+
*/
|
|
3116
|
+
walk(x: number, y: number, z: number, facing?: Facing): Promise<boolean>;
|
|
3117
|
+
|
|
3118
|
+
/**
|
|
3119
|
+
* Make the bot sit on an anchor
|
|
3120
|
+
* @param entity_id - The entity ID of the anchor
|
|
3121
|
+
* @param anchor_ix - The anchor index (default: 0)
|
|
3122
|
+
* @returns Promise resolving to operation success status
|
|
3123
|
+
* @example
|
|
3124
|
+
* ```typescript
|
|
3125
|
+
* const success = await bot.player.sit('chair_entity_id', 0);
|
|
3126
|
+
* ```
|
|
3127
|
+
*/
|
|
3128
|
+
sit(entity_id: string, anchor_ix?: number): Promise<boolean>;
|
|
3129
|
+
|
|
3130
|
+
/**
|
|
3131
|
+
* Teleport a user to specified coordinates with optional facing direction
|
|
3132
|
+
* @param user_id - The user ID of the player to teleport
|
|
3133
|
+
* @param x - The x coordinate to teleport to
|
|
3134
|
+
* @param y - The y coordinate to teleport to
|
|
3135
|
+
* @param z - The z coordinate to teleport to
|
|
3136
|
+
* @param facing - The direction the player should face after teleporting (default: 'FrontRight')
|
|
3137
|
+
* @throws {TypeError} If user_id is missing or coordinates are invalid
|
|
3138
|
+
* @example
|
|
3139
|
+
* await bot.player.teleport('68a7dd5eecae68acca580f41', 20, 10, 30, 'BackLeft');
|
|
3140
|
+
*/
|
|
3141
|
+
teleport(user_id: string, x: number, y: number, z: number, facing?: Facing): Promise<boolean>;
|
|
3142
|
+
|
|
3143
|
+
/**
|
|
3144
|
+
* Play an emote on a user
|
|
3145
|
+
* @param emote_id - The ID of the emote to play
|
|
3146
|
+
* @param user_id - The user ID to play the emote on (default: current bot user)
|
|
3147
|
+
* @throws {TypeError} If user_id or emote_id are missing or invalid
|
|
3148
|
+
* @example
|
|
3149
|
+
* // Play emote on bot
|
|
3150
|
+
* await bot.player.emote('dance');
|
|
3151
|
+
*
|
|
3152
|
+
* // Play emote on specific user
|
|
3153
|
+
* await bot.player.emote('wave', '68a7dd5eecae68acca580f41');
|
|
3154
|
+
*/
|
|
3155
|
+
emote(emote_id: string, user_id?: string | undefined): Promise<boolean>;
|
|
3156
|
+
|
|
3157
|
+
/**
|
|
3158
|
+
* Send a reaction to a user
|
|
3159
|
+
* @param user_id - The user ID to send the reaction to
|
|
3160
|
+
* @param reaction - The reaction type to send (must be one of: 'clap', 'heart', 'thumbs', 'wave', 'wink')
|
|
3161
|
+
* @throws {TypeError} If user_id or reaction are missing or invalid
|
|
3162
|
+
* @throws {Error} If reaction is not one of the valid reactions
|
|
3163
|
+
* @example
|
|
3164
|
+
* await bot.player.react('68a7dd5eecae68acca580f41', 'clap');
|
|
3165
|
+
* await bot.player.react('68a7dd5eecae68acca580f41', 'heart');
|
|
3166
|
+
*/
|
|
3167
|
+
react(user_id: string, reaction: Reactions): Promise<boolean>;
|
|
3168
|
+
|
|
3169
|
+
/**
|
|
3170
|
+
* Transport a user to another room
|
|
3171
|
+
* @param user_id - The user ID to transport to another room
|
|
3172
|
+
* @param room_id - The destination room ID
|
|
3173
|
+
* @throws {TypeError} If user_id or room_id are missing or invalid
|
|
3174
|
+
* @throws {Error} If attempting to transport the bot itself
|
|
3175
|
+
* @example
|
|
3176
|
+
* // Transport a user to another room
|
|
3177
|
+
* await bot.player.transport('68a7dd5eecae68acca580f41', '692125c2521b7580234d0f35');
|
|
3178
|
+
*
|
|
3179
|
+
* // This will throw an error:
|
|
3180
|
+
* // await bot.player.transport(bot.info.user.id, '692125c2521b7580234d0f35');
|
|
3181
|
+
*/
|
|
3182
|
+
transport(user_id: string, room_id: string): Promise<boolean>;
|
|
3183
|
+
|
|
3184
|
+
/**
|
|
3185
|
+
* Send a tip to a user
|
|
3186
|
+
* @param user_id - The user ID to tip (must be a non-empty string)
|
|
3187
|
+
* @param gold_bar - The amount of gold bars to tip (must be a number between 1 and 10,000 and a valid gold bar amount)
|
|
3188
|
+
* @throws {TypeError} When user_id is not a string or not in room, or gold_bar is invalid
|
|
3189
|
+
* @throws {Error} When the tip operation fails
|
|
3190
|
+
*/
|
|
3191
|
+
tip(user_id: string, gold_bar?: Goldbars): Promise<boolean>;
|
|
3192
|
+
|
|
3193
|
+
/**
|
|
3194
|
+
* Player Outfit management
|
|
3195
|
+
*/
|
|
3196
|
+
public outfit: {
|
|
3197
|
+
/**
|
|
3198
|
+
* Get a user's current outfit
|
|
3199
|
+
* @param user_id - The user ID to get the outfit for
|
|
3200
|
+
* @returns Promise resolving to array of outfit items
|
|
3201
|
+
* @example
|
|
3202
|
+
* ```typescript
|
|
3203
|
+
* // Get user's outfit
|
|
3204
|
+
* const outfit = await bot.player.outfit.get('68a7dd5eecae68acca580f41');
|
|
3205
|
+
* console.log(outfit);
|
|
3206
|
+
* // [
|
|
3207
|
+
* // {
|
|
3208
|
+
* // type: 'clothing',
|
|
3209
|
+
* // amount: 1,
|
|
3210
|
+
* // id: 'shirt-n_cooltshirt',
|
|
3211
|
+
* // account_bound: false,
|
|
3212
|
+
* // active_palette: null
|
|
3213
|
+
* // },
|
|
3214
|
+
* // ...
|
|
3215
|
+
* // ]
|
|
3216
|
+
* ```
|
|
3217
|
+
*/
|
|
3218
|
+
get(user_id: string): Promise<GetUserOutfitResponse[]>;
|
|
3219
|
+
}
|
|
3220
|
+
|
|
3221
|
+
/**
|
|
3222
|
+
* Moderation actions for room management
|
|
3223
|
+
*/
|
|
3224
|
+
public moderation: {
|
|
3225
|
+
/**
|
|
3226
|
+
* Kick a user from the room
|
|
3227
|
+
* @param user_id - The user ID of the user to kick
|
|
3228
|
+
* @throws {TypeError} If user_id is missing or invalid
|
|
3229
|
+
* @example
|
|
3230
|
+
* await bot.player.moderation.kick('68a7dd5eecae68acca580f41');
|
|
3231
|
+
*/
|
|
3232
|
+
kick(user_id: string): Promise<boolean>;
|
|
3233
|
+
|
|
3234
|
+
/**
|
|
3235
|
+
* Ban a user from the room for a specified duration
|
|
3236
|
+
* @param user_id - The user ID of the user to ban
|
|
3237
|
+
* @param duration - Ban duration in milliseconds (default: 1 hour)
|
|
3238
|
+
* @throws {TypeError} If user_id is missing or duration is invalid
|
|
3239
|
+
* @example
|
|
3240
|
+
* // Ban for 1 hour (default)
|
|
3241
|
+
* await bot.player.moderation.ban('68a7dd5eecae68acca580f41');
|
|
3242
|
+
*
|
|
3243
|
+
* // Ban for 30 minutes
|
|
3244
|
+
* await bot.player.moderation.ban('68a7dd5eecae68acca580f41', 30 * 60 * 1000);
|
|
3245
|
+
*
|
|
3246
|
+
* // Ban for 1 day
|
|
3247
|
+
* await bot.player.moderation.ban('68a7dd5eecae68acca580f41', 24 * 60 * 60 * 1000);
|
|
3248
|
+
*/
|
|
3249
|
+
ban(user_id: string, duration?: number): Promise<boolean>;
|
|
3250
|
+
|
|
3251
|
+
/**
|
|
3252
|
+
* Mute a user in the room for a specified duration
|
|
3253
|
+
* @param user_id - The user ID of the user to mute
|
|
3254
|
+
* @param duration - Mute duration in milliseconds (default: 5 minutes)
|
|
3255
|
+
* @throws {TypeError} If user_id is missing or duration is invalid
|
|
3256
|
+
* @example
|
|
3257
|
+
* // Mute for 5 minutes (default)
|
|
3258
|
+
* await bot.player.moderation.mute('68a7dd5eecae68acca580f41');
|
|
3259
|
+
*
|
|
3260
|
+
* // Mute for 1 hour
|
|
3261
|
+
* await bot.player.moderation.mute('68a7dd5eecae68acca580f41', 60 * 60 * 1000);
|
|
3262
|
+
*/
|
|
3263
|
+
mute(user_id: string, duration?: number): Promise<boolean>;
|
|
3264
|
+
|
|
3265
|
+
/**
|
|
3266
|
+
* Unmute a previously muted user in the room
|
|
3267
|
+
* @param user_id - The user ID of the user to unmute
|
|
3268
|
+
* @throws {TypeError} If user_id is missing or invalid
|
|
3269
|
+
* @example
|
|
3270
|
+
* await bot.player.moderation.unmute('68a7dd5eecae68acca580f41');
|
|
3271
|
+
*/
|
|
3272
|
+
unmute(user_id: string): Promise<boolean>;
|
|
3273
|
+
|
|
3274
|
+
/**
|
|
3275
|
+
* Unban a previously banned user from the room
|
|
3276
|
+
* @param user_id - The user ID of the user to unban
|
|
3277
|
+
* @throws {TypeError} If user_id is missing or invalid
|
|
3278
|
+
* @example
|
|
3279
|
+
* await bot.player.moderation.unban('68a7dd5eecae68acca580f41');
|
|
3280
|
+
*/
|
|
3281
|
+
unban(user_id: string): Promise<boolean>;
|
|
3282
|
+
}
|
|
3283
|
+
}
|
|
3284
|
+
|
|
3285
|
+
declare class Logger {
|
|
3286
|
+
/**
|
|
3287
|
+
* Generic log method for custom log levels
|
|
3288
|
+
* @param level - The log level
|
|
3289
|
+
* @param method - The method name where the log originated
|
|
3290
|
+
* @param message - The main log message
|
|
3291
|
+
* @param data - Optional data object to include in the log
|
|
3292
|
+
* @example
|
|
3293
|
+
* logger.log('CUSTOM', 'myMethod', 'Custom log message', { userId: '68a7dd5eecae68acca580f41' });
|
|
3294
|
+
*/
|
|
3295
|
+
log(level: string, method: string, message: string, data?: any): void;
|
|
3296
|
+
|
|
3297
|
+
/**
|
|
3298
|
+
* Log a success message (green color)
|
|
3299
|
+
* @param method - The method name where the log originated
|
|
3300
|
+
* @param message - The success message
|
|
3301
|
+
* @param data - Optional data object to include in the log
|
|
3302
|
+
* @example
|
|
3303
|
+
* logger.success('walk', 'Successfully walked to destination', { x: 10, y: 5, z: 15 });
|
|
3304
|
+
*/
|
|
3305
|
+
success(method: string, message: string, data?: any): void;
|
|
3306
|
+
|
|
3307
|
+
/**
|
|
3308
|
+
* Log an error message (red color)
|
|
3309
|
+
* @param method - The method name where the log originated
|
|
3310
|
+
* @param message - The error message
|
|
3311
|
+
* @param data - Optional data object to include in the log
|
|
3312
|
+
* @example
|
|
3313
|
+
* logger.error('teleport', 'Failed to teleport user', { userId: '68a7dd5eecae68acca580f41', error: 'Invalid coordinates' });
|
|
3314
|
+
*/
|
|
3315
|
+
error(method: string, message: string, data?: any): void;
|
|
3316
|
+
|
|
3317
|
+
/**
|
|
3318
|
+
* Log a warning message (yellow color)
|
|
3319
|
+
* @param method - The method name where the log originated
|
|
3320
|
+
* @param message - The warning message
|
|
3321
|
+
* @param data - Optional data object to include in the log
|
|
3322
|
+
* @example
|
|
3323
|
+
* logger.warn('moderation.ban', 'User was banned', { userId: '68a7dd5eecae68acca580f41', duration: 3600000 });
|
|
3324
|
+
*/
|
|
3325
|
+
warn(method: string, message: string, data?: any): void;
|
|
3326
|
+
|
|
3327
|
+
/**
|
|
3328
|
+
* Log an info message (blue color)
|
|
3329
|
+
* @param method - The method name where the log originated
|
|
3330
|
+
* @param message - The info message
|
|
3331
|
+
* @param data - Optional data object to include in the log
|
|
3332
|
+
* @example
|
|
3333
|
+
* logger.info('emote', 'Playing emote for user', { userId: '68a7dd5eecae68acca580f41', emoteId: 'dance' });
|
|
3334
|
+
*/
|
|
3335
|
+
info(method: string, message: string, data?: any): void;
|
|
3336
|
+
|
|
3337
|
+
/**
|
|
3338
|
+
* Log a debug message (magenta color)
|
|
3339
|
+
* @param method - The method name where the log originated
|
|
3340
|
+
* @param message - The debug message
|
|
3341
|
+
* @param data - Optional data object to include in the log
|
|
3342
|
+
* @example
|
|
3343
|
+
* logger.debug('react', 'Validating reaction parameters', { userId: '68a7dd5eecae68acca580f41', reaction: 'wave' });
|
|
3344
|
+
*/
|
|
3345
|
+
debug(method: string, message: string, data?: any): void;
|
|
3346
|
+
}
|
|
3347
|
+
|
|
3348
|
+
interface BotUtils {
|
|
3349
|
+
/**
|
|
3350
|
+
* Logger instance for structured, color-coded logging throughout the application
|
|
3351
|
+
* Provides different log levels (SUCCESS, ERROR, WARN, INFO, DEBUG) with timestamps and method tracking
|
|
3352
|
+
*
|
|
3353
|
+
* @example
|
|
3354
|
+
* // Basic logging
|
|
3355
|
+
* bot.utils.logger.info('connection', 'Bot connected successfully');
|
|
3356
|
+
* bot.utils.logger.error('auth', 'Authentication failed', { userId: '68a7dd5eecae68acca580f41' });
|
|
3357
|
+
*
|
|
3358
|
+
* // With different levels
|
|
3359
|
+
* bot.utils.logger.success('payment', 'Payment processed');
|
|
3360
|
+
* bot.utils.logger.warn('moderation', 'User warning issued');
|
|
3361
|
+
* bot.utils.logger.debug('websocket', 'Message received', { type: message._type });
|
|
3362
|
+
*/
|
|
3363
|
+
logger: Logger;
|
|
3364
|
+
|
|
3365
|
+
/**
|
|
3366
|
+
* Utility method to create a delay/pause in execution
|
|
3367
|
+
* Returns a Promise that resolves after the specified time, useful for rate limiting,
|
|
3368
|
+
* artificial delays, or waiting between methods
|
|
3369
|
+
*
|
|
3370
|
+
* @param ms - Delay duration in milliseconds
|
|
3371
|
+
* @returns Promise that resolves after the specified delay
|
|
3372
|
+
*
|
|
3373
|
+
* @example
|
|
3374
|
+
* // Basic delay
|
|
3375
|
+
* await bot.utils.sleep(1000); // Wait 1 second
|
|
3376
|
+
*
|
|
3377
|
+
* // Rate limiting between messages
|
|
3378
|
+
* await bot.message.send("First message");
|
|
3379
|
+
* await bot.utils.sleep(500); // Wait 500ms
|
|
3380
|
+
* await bot.message.send("Second message");
|
|
3381
|
+
*
|
|
3382
|
+
* // Artificial delay for user experience
|
|
3383
|
+
* await bot.utils.sleep(2000); // Wait 2 seconds before response
|
|
3384
|
+
* await bot.message.send("Processing complete!");
|
|
3385
|
+
*
|
|
3386
|
+
* // In loops with delays
|
|
3387
|
+
* for (let i = 0; i < 5; i++) {
|
|
3388
|
+
* await bot.message.send(`Message ${i + 1}`);
|
|
3389
|
+
* await bot.utils.sleep(1000); // Wait 1 second between messages
|
|
3390
|
+
* }
|
|
3391
|
+
*/
|
|
3392
|
+
sleep(ms: number): Promise<boolean>;
|
|
3393
|
+
|
|
3394
|
+
DanceFloor: DanceFloor
|
|
3395
|
+
|
|
3396
|
+
/**
|
|
3397
|
+
* Creates a new CooldownManager instance with empty cooldown collections.
|
|
3398
|
+
*/
|
|
3399
|
+
cooldown: CooldownManager
|
|
3400
|
+
|
|
3401
|
+
/**
|
|
3402
|
+
* Role-based permission management with Web API auto-sync
|
|
3403
|
+
*/
|
|
3404
|
+
permissions: RoleManager;
|
|
3405
|
+
}
|
|
3406
|
+
|
|
3407
|
+
declare class RoomClass {
|
|
3408
|
+
/**
|
|
3409
|
+
* Room privilege methods
|
|
3410
|
+
*/
|
|
3411
|
+
public privilege: {
|
|
3412
|
+
/**
|
|
3413
|
+
* Get room privilege of a specific user
|
|
3414
|
+
* @param user_id - The user ID to check privilege for
|
|
3415
|
+
* @returns Promise resolving to user privileges
|
|
3416
|
+
* @example
|
|
3417
|
+
* ```typescript
|
|
3418
|
+
* const privileges = await bot.room.privilege.get('68a7dd5eecae68acca580f41');
|
|
3419
|
+
* console.log(privileges.moderator); // true/false
|
|
3420
|
+
* console.log(privileges.designer); // true/false
|
|
3421
|
+
* ```
|
|
3422
|
+
*/
|
|
3423
|
+
get(user_id: string): Promise<GetRoomPrivilegeResponse>;
|
|
3424
|
+
|
|
3425
|
+
/**
|
|
3426
|
+
* Check if a user is a moderator in the room
|
|
3427
|
+
* @param user_id - The user ID to check
|
|
3428
|
+
* @returns Promise resolving to boolean indicating moderator status
|
|
3429
|
+
* @example
|
|
3430
|
+
* ```typescript
|
|
3431
|
+
* const isMod = await bot.room.privilege.isModerator('68a7dd5eecae68acca580f41');
|
|
3432
|
+
* if (isMod) {
|
|
3433
|
+
* console.log('User is a moderator');
|
|
3434
|
+
* }
|
|
3435
|
+
* ```
|
|
3436
|
+
*/
|
|
3437
|
+
isModerator(user_id: string): Promise<boolean>;
|
|
3438
|
+
|
|
3439
|
+
/**
|
|
3440
|
+
* Check if a user is a designer in the room
|
|
3441
|
+
* @param user_id - The user ID to check
|
|
3442
|
+
* @returns Promise resolving to boolean indicating designer status
|
|
3443
|
+
* @example
|
|
3444
|
+
* ```typescript
|
|
3445
|
+
* const isDesigner = await bot.room.privilege.isDesigner('68a7dd5eecae68acca580f41');
|
|
3446
|
+
* if (isDesigner) {
|
|
3447
|
+
* console.log('User is a designer');
|
|
3448
|
+
* }
|
|
3449
|
+
* ```
|
|
3450
|
+
*/
|
|
3451
|
+
isDesigner(user_id: string): Promise<boolean>;
|
|
3452
|
+
}
|
|
3453
|
+
|
|
3454
|
+
/**
|
|
3455
|
+
* Designer privilege management
|
|
3456
|
+
*/
|
|
3457
|
+
public designer: {
|
|
3458
|
+
/**
|
|
3459
|
+
* Add designer privileges to a user
|
|
3460
|
+
* @param user_id - The user ID to grant designer privileges to
|
|
3461
|
+
* @returns Promise resolving to operation success status
|
|
3462
|
+
* @example
|
|
3463
|
+
* ```typescript
|
|
3464
|
+
* const success = await bot.room.designer.add('68a7dd5eecae68acca580f41');
|
|
3465
|
+
* if (success) {
|
|
3466
|
+
* console.log('User is now a designer');
|
|
3467
|
+
* }
|
|
3468
|
+
* ```
|
|
3469
|
+
*/
|
|
3470
|
+
add(user_id: string): Promise<boolean>;
|
|
3471
|
+
|
|
3472
|
+
/**
|
|
3473
|
+
* Remove designer privileges from a user
|
|
3474
|
+
* @param user_id - The user ID to remove designer privileges from
|
|
3475
|
+
* @returns Promise resolving to operation success status
|
|
3476
|
+
* @example
|
|
3477
|
+
* ```typescript
|
|
3478
|
+
* const success = await bot.room.designer.remove('68a7dd5eecae68acca580f41');
|
|
3479
|
+
* if (success) {
|
|
3480
|
+
* console.log('User is no longer a designer');
|
|
3481
|
+
* }
|
|
3482
|
+
* ```
|
|
3483
|
+
*/
|
|
3484
|
+
remove(user_id: string): Promise<boolean>;
|
|
3485
|
+
}
|
|
3486
|
+
|
|
3487
|
+
/**
|
|
3488
|
+
* Moderator privilege management
|
|
3489
|
+
*/
|
|
3490
|
+
public moderator: {
|
|
3491
|
+
/**
|
|
3492
|
+
* Add moderator privileges to a user
|
|
3493
|
+
* @param user_id - The user ID to grant moderator privileges to
|
|
3494
|
+
* @returns Promise resolving to operation success status
|
|
3495
|
+
* @example
|
|
3496
|
+
* ```typescript
|
|
3497
|
+
* const success = await bot.room.moderator.add('68a7dd5eecae68acca580f41');
|
|
3498
|
+
* if (success) {
|
|
3499
|
+
* console.log('User is now a moderator');
|
|
3500
|
+
* }
|
|
3501
|
+
* ```
|
|
3502
|
+
*/
|
|
3503
|
+
add(user_id: string): Promise<boolean>;
|
|
3504
|
+
|
|
3505
|
+
/**
|
|
3506
|
+
* Remove moderator privileges from a user
|
|
3507
|
+
* @param user_id - The user ID to remove moderator privileges from
|
|
3508
|
+
* @returns Promise resolving to operation success status
|
|
3509
|
+
* @example
|
|
3510
|
+
* ```typescript
|
|
3511
|
+
* const success = await bot.room.moderator.remove('68a7dd5eecae68acca580f41');
|
|
3512
|
+
* if (success) {
|
|
3513
|
+
* console.log('User is no longer a moderator');
|
|
3514
|
+
* }
|
|
3515
|
+
* ```
|
|
3516
|
+
*/
|
|
3517
|
+
remove(user_id: string): Promise<boolean>;
|
|
3518
|
+
}
|
|
3519
|
+
|
|
3520
|
+
/**
|
|
3521
|
+
* Room user management methods
|
|
3522
|
+
*/
|
|
3523
|
+
public users: {
|
|
3524
|
+
/**
|
|
3525
|
+
* Get all users currently in the room
|
|
3526
|
+
* @returns Promise resolving to array of users with their positions
|
|
3527
|
+
* @example
|
|
3528
|
+
* ```typescript
|
|
3529
|
+
* const users = await bot.room.users.get();
|
|
3530
|
+
* ```
|
|
3531
|
+
*/
|
|
3532
|
+
get(): Promise<Array<[
|
|
3533
|
+
User,
|
|
3534
|
+
Position
|
|
3535
|
+
]>>;
|
|
3536
|
+
|
|
3537
|
+
/**
|
|
3538
|
+
* Get user ID by username
|
|
3539
|
+
* @param username - The username to look up
|
|
3540
|
+
* @returns Promise resolving to user ID
|
|
3541
|
+
* @example
|
|
3542
|
+
* ```typescript
|
|
3543
|
+
* const userId = await bot.room.users.id('Unfairly');
|
|
3544
|
+
* ```
|
|
3545
|
+
*/
|
|
3546
|
+
id(username: string): Promise<string> | null;
|
|
3547
|
+
|
|
3548
|
+
/**
|
|
3549
|
+
* Get username by user ID
|
|
3550
|
+
* @param id - The user ID to look up
|
|
3551
|
+
* @returns Promise resolving to username
|
|
3552
|
+
* ```typescript
|
|
3553
|
+
* const username = await bot.room.users.username('692118c325513614015cddbf');
|
|
3554
|
+
* ```
|
|
3555
|
+
*/
|
|
3556
|
+
username(id: string): Promise<string> | null;
|
|
3557
|
+
|
|
3558
|
+
/**
|
|
3559
|
+
* Get user position by username or user ID
|
|
3560
|
+
* @param identifier - Username or user ID
|
|
3561
|
+
* @returns Promise resolving to user position
|
|
3562
|
+
* @example
|
|
3563
|
+
* ```typescript
|
|
3564
|
+
* const pos = await bot.room.users.position('Unfairly');
|
|
3565
|
+
* const pos = await bot.room.users.position('692118c325513614015cddbf');
|
|
3566
|
+
* ```
|
|
3567
|
+
*/
|
|
3568
|
+
position(identifier: string): Promise<Position | AnchorPosition>;
|
|
3569
|
+
}
|
|
3570
|
+
|
|
3571
|
+
/**
|
|
3572
|
+
* Room voice chat methods
|
|
3573
|
+
*/
|
|
3574
|
+
public voice: {
|
|
3575
|
+
/**
|
|
3576
|
+
* Check the current voice chat status in the room (valid only if the bot were created on the room owner account)
|
|
3577
|
+
* @returns Promise resolving an Object for success check or message on failed
|
|
3578
|
+
* @example
|
|
3579
|
+
* ```typescript
|
|
3580
|
+
* const status = await bot.room.voice.check();
|
|
3581
|
+
*
|
|
3582
|
+
* // if success
|
|
3583
|
+
* console.log(status.autoSpeakersId) // [ '6734bf...', '68a73d...' ]
|
|
3584
|
+
*
|
|
3585
|
+
* if failed
|
|
3586
|
+
* console.log(status.message)
|
|
3587
|
+
* ```
|
|
3588
|
+
*/
|
|
3589
|
+
check(): Promise<ValidVoiceCheck | InvalidVoiceCheck>
|
|
3590
|
+
|
|
3591
|
+
/**
|
|
3592
|
+
* Invite a user to speak in voice chat
|
|
3593
|
+
* @param user_id - The user ID to invite as speaker
|
|
3594
|
+
* @returns Promise resolving to operation success status
|
|
3595
|
+
* @example
|
|
3596
|
+
* ```typescript
|
|
3597
|
+
* const success = await bot.room.voice.invite('68a7dd5eecae68acca580f41');
|
|
3598
|
+
* ```
|
|
3599
|
+
*/
|
|
3600
|
+
invite(user_id: string): Promise<boolean>;
|
|
3601
|
+
|
|
3602
|
+
/**
|
|
3603
|
+
* Remove a user from voice chat speakers
|
|
3604
|
+
* @param user_id - The user ID to remove from speakers
|
|
3605
|
+
* @returns Promise resolving to operation success status
|
|
3606
|
+
* @example
|
|
3607
|
+
* ```typescript
|
|
3608
|
+
* const success = await bot.room.voice.remove('68a7dd5eecae68acca580f41');
|
|
3609
|
+
* ```
|
|
3610
|
+
*/
|
|
3611
|
+
remove(user_id: string): Promise<boolean>;
|
|
3612
|
+
}
|
|
3613
|
+
}
|
|
3614
|
+
|
|
3615
|
+
/**
|
|
3616
|
+
* Logger configuration - controls how bot messages appear in console
|
|
3617
|
+
*/
|
|
3618
|
+
interface LoggerOptions {
|
|
3619
|
+
/** Show time in logs? (true = [2023-10-05T14:30:00.68a7dd5eecae68acca580f41Z] [INFO]) */
|
|
3620
|
+
showTimestamp?: boolean;
|
|
3621
|
+
/** Show method name? (true = [connect]: Connected) */
|
|
3622
|
+
showMethodName?: boolean;
|
|
3623
|
+
/** Use colors? (true = green success, red errors) */
|
|
3624
|
+
colors?: boolean;
|
|
3625
|
+
}
|
|
3626
|
+
|
|
3627
|
+
/**
|
|
3628
|
+
* Bot connection settings - controls how bot handles disconnections
|
|
3629
|
+
*/
|
|
3630
|
+
interface HighriseOptions {
|
|
3631
|
+
/** How logs look in console */
|
|
3632
|
+
LoggerOptions?: LoggerOptions;
|
|
3633
|
+
/** Wait time between reconnect tries (milliseconds) */
|
|
3634
|
+
reconnectDelay: number;
|
|
3635
|
+
/** Auto-reconnect if disconnected? */
|
|
3636
|
+
autoReconnect: boolean;
|
|
3637
|
+
/** Custom roles to create on startup */
|
|
3638
|
+
customRoles?: string[];
|
|
3639
|
+
}
|
|
3640
|
+
|
|
3641
|
+
/**
|
|
3642
|
+
* Configuration options for request senders
|
|
3643
|
+
*/
|
|
3644
|
+
interface SenderConfig {
|
|
3645
|
+
/**
|
|
3646
|
+
* Default timeout for requests waiting in milliseconds (default: 10000ms)
|
|
3647
|
+
*/
|
|
3648
|
+
defaultTimeout?: number;
|
|
3649
|
+
|
|
3650
|
+
/**
|
|
3651
|
+
* Maximum number of retry attempts for failed requests (default: 2)
|
|
3652
|
+
*/
|
|
3653
|
+
maxRetries?: number;
|
|
3654
|
+
|
|
3655
|
+
/**
|
|
3656
|
+
* Delay between retry attempts in milliseconds (default: 100)
|
|
3657
|
+
*/
|
|
3658
|
+
retryDelay?: number;
|
|
3659
|
+
}
|
|
3660
|
+
|
|
3661
|
+
declare class Highrise {
|
|
3662
|
+
/**
|
|
3663
|
+
* Creates a new Highrise bot instance
|
|
3664
|
+
* @param Events - Array of event names to listen for
|
|
3665
|
+
* @param options - Configuration options for the bot
|
|
3666
|
+
*/
|
|
3667
|
+
constructor(Events: EventType[], options?: HighriseOptions);
|
|
3668
|
+
|
|
3669
|
+
/** Public message actions */
|
|
3670
|
+
public message: MessageClass;
|
|
3671
|
+
|
|
3672
|
+
/** Private whisper actions */
|
|
3673
|
+
public whisper: WhisperClass;
|
|
3674
|
+
|
|
3675
|
+
/** Direct message and conversation actions */
|
|
3676
|
+
public direct: DirectClass;
|
|
3677
|
+
|
|
3678
|
+
/** Player movement and interaction actions */
|
|
3679
|
+
public player: PlayerClass;
|
|
3680
|
+
|
|
3681
|
+
/** Bot information and state */
|
|
3682
|
+
public info: BotInformation;
|
|
3683
|
+
|
|
3684
|
+
/** Utility methods and tools for bot development and management */
|
|
3685
|
+
public utils: BotUtils;
|
|
3686
|
+
|
|
3687
|
+
/** Room methods and management */
|
|
3688
|
+
public room: RoomClass;
|
|
3689
|
+
|
|
3690
|
+
/** Inventory management operations */
|
|
3691
|
+
public inventory: InventoryClass;
|
|
3692
|
+
|
|
3693
|
+
/** WebAPI Class for external Highrise API calls */
|
|
3694
|
+
public webapi: WebApi
|
|
3695
|
+
|
|
3696
|
+
/** Await system for waiting for specific events with filters */
|
|
3697
|
+
public await: AwaitClass
|
|
3698
|
+
|
|
3699
|
+
/**
|
|
3700
|
+
* Hidden channel forbot-to-bot communication
|
|
3701
|
+
* Allows sending and receiving messages between all bots in the room
|
|
3702
|
+
*
|
|
3703
|
+
* @example
|
|
3704
|
+
* ```typescript
|
|
3705
|
+
* // Send to channel
|
|
3706
|
+
* await bot.channel.send('Hello other bots!', ['greeting']);
|
|
3707
|
+
*
|
|
3708
|
+
* // Listen for messages
|
|
3709
|
+
* bot.channel.on(['greeting'], (data) => {
|
|
3710
|
+
* console.log(`Bot ${data.senderId} says: ${data.message}`);
|
|
3711
|
+
* });
|
|
3712
|
+
* ```
|
|
3713
|
+
*/
|
|
3714
|
+
public channel: Channel;
|
|
3715
|
+
|
|
3716
|
+
/**
|
|
3717
|
+
* Cache management system for efficient data storage and retrieval
|
|
3718
|
+
* Provides optimized memory usage and fast lookups for frequently accessed data
|
|
3719
|
+
*/
|
|
3720
|
+
public cache: {
|
|
3721
|
+
/**
|
|
3722
|
+
* Movement cache for efficient user position tracking
|
|
3723
|
+
* Automatically handles position changes and memory optimization
|
|
3724
|
+
*/
|
|
3725
|
+
position: MovementCache
|
|
3726
|
+
}
|
|
3727
|
+
|
|
3728
|
+
/**
|
|
3729
|
+
* Authenticate and connect the bot to a Highrise room
|
|
3730
|
+
* @param token - Bot authentication token (64 characters)
|
|
3731
|
+
* @param room_id - Room ID to connect to (24 characters)
|
|
3732
|
+
* @throws {Error} If token, room_id, or events are invalid
|
|
3733
|
+
* @example
|
|
3734
|
+
* await bot.login('your_64_character_bot_token_here', 'room_id_24_characters_long');
|
|
3735
|
+
*/
|
|
3736
|
+
login(token: string, room_id: string): Promise<void>;
|
|
3737
|
+
|
|
3738
|
+
/**
|
|
3739
|
+
* Manually disconnect the WebSocket connection and disable auto-reconnect
|
|
3740
|
+
* Performs graceful shutdown by:
|
|
3741
|
+
* - Disabling auto-reconnection
|
|
3742
|
+
* - Cleaning up intervals and timeouts
|
|
3743
|
+
* - Closing the WebSocket connection with code 1000 (normal closure)
|
|
3744
|
+
* - Resetting connection state
|
|
3745
|
+
*
|
|
3746
|
+
* @example
|
|
3747
|
+
* // Gracefully disconnect from Highrise
|
|
3748
|
+
* bot.disconnect();
|
|
3749
|
+
*
|
|
3750
|
+
* // Example in a cleanup scenario
|
|
3751
|
+
* process.on('SIGINT', () => {
|
|
3752
|
+
* console.log('Shutting down gracefully...');
|
|
3753
|
+
* bot.disconnect();
|
|
3754
|
+
* process.exit(0);
|
|
3755
|
+
* });
|
|
3756
|
+
*
|
|
3757
|
+
* @throws {Error} If there are issues during the cleanup process
|
|
3758
|
+
* @emits Various cleanup events during the disconnection process
|
|
3759
|
+
*/
|
|
3760
|
+
disconnect(): void;
|
|
3761
|
+
|
|
3762
|
+
/**
|
|
3763
|
+
* Return system metrics
|
|
3764
|
+
* Shows real-time statistics about bot performance, cache usage, and connection status
|
|
3765
|
+
*/
|
|
3766
|
+
getMetrics(): MetricData
|
|
3767
|
+
|
|
3768
|
+
/**
|
|
3769
|
+
* Configures the request/response and fire-and-forget senders
|
|
3770
|
+
* @param config - Configuration object for sender behavior
|
|
3771
|
+
* @example
|
|
3772
|
+
* ```typescript
|
|
3773
|
+
* // Configure with custom timeout and retries
|
|
3774
|
+
* bot.configureSenders({
|
|
3775
|
+
* defaultTimeout: 15000, // 15 second timeout
|
|
3776
|
+
* maxRetries: 3, // 3 retry attempts
|
|
3777
|
+
* retryDelay: 200 // 200ms between retries
|
|
3778
|
+
* });
|
|
3779
|
+
*
|
|
3780
|
+
* // Configure only timeout
|
|
3781
|
+
* bot.configureSenders({
|
|
3782
|
+
* defaultTimeout: 5000 // 5 second timeout only
|
|
3783
|
+
* });
|
|
3784
|
+
*
|
|
3785
|
+
* // Reset to defaults (empty config)
|
|
3786
|
+
* bot.configureSenders();
|
|
3787
|
+
* ```
|
|
3788
|
+
* @throws {Error} If configuration values are outside valid ranges
|
|
3789
|
+
*/
|
|
3790
|
+
configureSenders(config?: SenderConfig): void;
|
|
3791
|
+
|
|
3792
|
+
/**
|
|
3793
|
+
* Register an event listener
|
|
3794
|
+
* @param event - Event name to listen for
|
|
3795
|
+
* @param listener - Async callback function to handle the event
|
|
3796
|
+
* @returns The Highrise instance for chaining
|
|
3797
|
+
*/
|
|
3798
|
+
on<K extends keyof EventMap>(event: K, listener: (...args: EventMap[K]) => Promise<void>): this;
|
|
3799
|
+
on(event: string, listener: (...args: any[]) => Promise<void>): this;
|
|
3800
|
+
|
|
3801
|
+
/**
|
|
3802
|
+
* Register a one-time event listener
|
|
3803
|
+
* @param event - Event name to listen for
|
|
3804
|
+
* @param listener - Async callback function to handle the event
|
|
3805
|
+
* @returns The Highrise instance for chaining
|
|
3806
|
+
*/
|
|
3807
|
+
once<K extends keyof EventMap>(event: K, listener: (...args: EventMap[K]) => Promise<void>): this;
|
|
3808
|
+
once(event: string, listener: (...args: any[]) => Promise<void>): this;
|
|
3809
|
+
|
|
3810
|
+
/**
|
|
3811
|
+
* Emit an event
|
|
3812
|
+
* @param event - Event name to emit
|
|
3813
|
+
* @param args - Arguments to pass to event listeners
|
|
3814
|
+
* @returns True if the event had listeners, false otherwise
|
|
3815
|
+
*/
|
|
3816
|
+
emit<K extends keyof EventMap>(event: K, ...args: EventMap[K]): boolean;
|
|
3817
|
+
emit(event: string, ...args: any[]): boolean;
|
|
3818
|
+
}
|
|
3819
|
+
|
|
3820
|
+
export { Highrise, WebApi }
|