@shaunlwm/pickle.ts 1.10.0 → 1.12.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/dist/index.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- import * as socket_io_client from 'socket.io-client';
2
1
  import { Socket, ManagerOptions, SocketOptions } from 'socket.io-client';
3
2
  import { EventEmitter } from 'node:events';
4
3
 
@@ -26,6 +25,8 @@ type NormalizedConnectionProfile = {
26
25
  type ServerInfo = {
27
26
  name: string;
28
27
  population: number;
28
+ /** CPPS.lol only: exact number of penguins online. */
29
+ users?: number;
29
30
  };
30
31
  type LoginOptions = {
31
32
  username: string;
@@ -50,6 +51,55 @@ type QueueUpdate = {
50
51
  queueLength: number;
51
52
  };
52
53
 
54
+ type ClientLifecyclePhase = "transport_connecting" | "queueing" | "authenticating" | "joining_session" | "awaiting_initial_state" | "ready" | "disconnecting" | "disconnected";
55
+ type ClientLifecycleUpdate = {
56
+ phase: ClientLifecyclePhase;
57
+ occurredAt: number;
58
+ queue?: QueueUpdate;
59
+ };
60
+ type ClientOperationOptions = {
61
+ signal?: AbortSignal;
62
+ timeoutMs?: number;
63
+ };
64
+ type ClientConnectionTimeouts = {
65
+ loginMs: number;
66
+ transportMs: number;
67
+ /** Maximum silence between queue updates, not total time spent queued. */
68
+ queueMs: number;
69
+ authenticationMs: number;
70
+ initialStateMs: number;
71
+ requestMs: number;
72
+ };
73
+ declare const DEFAULT_CLIENT_CONNECTION_TIMEOUTS: {
74
+ readonly loginMs: 20000;
75
+ readonly transportMs: 20000;
76
+ readonly queueMs: 300000;
77
+ readonly authenticationMs: 20000;
78
+ readonly initialStateMs: 15000;
79
+ readonly requestMs: 15000;
80
+ };
81
+ type ClientDisconnectInfo = {
82
+ intentional: boolean;
83
+ reason: string | null;
84
+ occurredAt: number;
85
+ };
86
+
87
+ type ClientOperationErrorCategory = "login_timeout" | "login_rejected" | "invalid_credentials" | "account_banned" | "queue_timeout" | "transport_error" | "auth_timeout" | "auth_failed" | "initial_state_timeout" | "operation_timeout" | "unsupported_operation" | "aborted" | "disconnected" | "kicked" | "server_error";
88
+ type ClientOperationErrorOptions = {
89
+ category: ClientOperationErrorCategory;
90
+ phase: ClientLifecyclePhase;
91
+ retryable: boolean;
92
+ message: string;
93
+ cause?: unknown;
94
+ };
95
+ declare function sanitizeClientErrorMessage(message: string): string;
96
+ declare class ClientOperationError extends Error {
97
+ readonly category: ClientOperationErrorCategory;
98
+ readonly phase: ClientLifecyclePhase;
99
+ readonly retryable: boolean;
100
+ constructor(options: ClientOperationErrorOptions);
101
+ }
102
+
53
103
  /** Core appearance slots shared by all servers (CPJourney, CPLegacy, NewCP). */
54
104
  type PlayerAppearance = {
55
105
  color: number;
@@ -102,7 +152,24 @@ type RoomUser = PlayerAppearance & {
102
152
  x: number;
103
153
  y: number;
104
154
  frame: number;
105
- /** Adapter-specific extras. See each adapter's normalizeUser for keys. */
155
+ /**
156
+ * Adapter-specific extras. See each adapter's normalizeUser for keys.
157
+ *
158
+ * **CPJourney** overlay appearance slots (number):
159
+ * `hat`, `face_mask`, `neck_scarf`, `body_shirt`, `hand_glove`
160
+ *
161
+ * **CPJourney** user state:
162
+ * `transform` (number) — costume ID, 0 = none
163
+ * `walkingPuffleType` (number | null) — puffle species
164
+ * `openSprite` (string | null) — sprite state e.g. "1_3"
165
+ * `mascotGiveaway` (number | null) — non-null = mascot, value = giveaway item ID
166
+ * `iglooOpen` (number) — 0/1
167
+ * `iglooBounds` (number) — 0/1
168
+ * `igloo_slot` (number) — active igloo slot
169
+ * `currentLayer` (number) — rendering layer
170
+ * `fireRank` (number) — fire ninja rank 0–5
171
+ * `isInvisible` (boolean) — mascot visibility flag
172
+ */
106
173
  meta: Record<string, unknown>;
107
174
  /** Original unnormalized server response */
108
175
  _raw: Record<string, unknown>;
@@ -144,7 +211,78 @@ type Postcard = {
144
211
  senderId: number;
145
212
  postcardId: number;
146
213
  extra: string | null;
147
- date: string;
214
+ /** CPJourney MessagePack decodes this as a Date; other adapters may use strings. */
215
+ date: Date | string;
216
+ };
217
+ /** A puffle summary, optionally including CPJourney's full care state. */
218
+ type Puffle = {
219
+ id: number;
220
+ type: number;
221
+ userId?: number;
222
+ name?: string;
223
+ energy?: number;
224
+ health?: number;
225
+ rest?: number;
226
+ experience?: number;
227
+ level?: number;
228
+ adoption_date?: Record<string, unknown>;
229
+ last_feed?: Record<string, unknown>;
230
+ last_slept?: Record<string, unknown>;
231
+ postcard_hungry?: boolean;
232
+ dead?: number;
233
+ ran_away?: number;
234
+ last_dig?: number;
235
+ in_backyard?: number;
236
+ backyard_supplies?: number;
237
+ walking?: boolean;
238
+ backyard?: boolean;
239
+ };
240
+ /** CPJourney puffle care values returned by get_wellbeing/update_wellbeing. */
241
+ type PuffleWellbeing = {
242
+ puffleId: number;
243
+ energy: number;
244
+ health: number;
245
+ rest: number;
246
+ name: string;
247
+ type: number;
248
+ level: number;
249
+ experience: number;
250
+ inBackyard?: number;
251
+ backyardSupplyCost?: number;
252
+ backyardSuppliesEmpty?: boolean;
253
+ backyardPuffleCount?: number;
254
+ };
255
+ /** Furniture placement sent by CPJourney's igloo editor. */
256
+ type IglooFurniturePlacement = {
257
+ furnitureId: number;
258
+ x: number;
259
+ y: number;
260
+ rotation: number;
261
+ frame: number;
262
+ depth: number;
263
+ /** Present in join_igloo snapshots but omitted by editor updates. */
264
+ slot?: number;
265
+ };
266
+ /** Common CPJourney igloo/music store item fields. */
267
+ type IglooStoreItem = {
268
+ id: string;
269
+ name: string;
270
+ cost: number;
271
+ store: number;
272
+ seasonal: number;
273
+ new: number;
274
+ active?: number;
275
+ patched?: number;
276
+ timeAdded?: number;
277
+ };
278
+ /** CPJourney furniture catalog item fields. */
279
+ type FurnitureStoreItem = IglooStoreItem & {
280
+ type: number;
281
+ sort: number;
282
+ member: number;
283
+ bait: number;
284
+ max: number;
285
+ fps?: number;
148
286
  };
149
287
  type NinjaCard = {
150
288
  id: number;
@@ -204,8 +342,19 @@ type SocketIoConnectionOptions = Partial<ManagerOptions & SocketOptions> & {
204
342
  extraHeaders?: Record<string, string>;
205
343
  origin?: string;
206
344
  };
345
+ type AdapterMessage = {
346
+ action: string;
347
+ args: Record<string, unknown>;
348
+ };
207
349
  type ConnectOptions = {
350
+ signal?: AbortSignal;
351
+ timeouts?: Partial<ClientConnectionTimeouts>;
208
352
  onQueueUpdate?: (update: QueueUpdate) => void;
353
+ onLifecycleUpdate?: (update: ClientLifecycleUpdate) => void;
354
+ /** @internal Normalized message delivery installed before session join. */
355
+ onMessage?: (message: AdapterMessage) => void;
356
+ /** @internal Transport disconnect delivery installed before session join. */
357
+ onDisconnect?: (reason: string | null) => void;
209
358
  };
210
359
  declare abstract class BaseAdapter {
211
360
  protected readonly connectionProfile: NormalizedConnectionProfile;
@@ -214,10 +363,14 @@ declare abstract class BaseAdapter {
214
363
  loginMessage: string | null;
215
364
  loginStatus: "active" | "banned";
216
365
  constructor(connectionProfile?: NormalizedConnectionProfile);
217
- abstract login(options: LoginOptions | TokenLoginOptions): Promise<LoginResult>;
366
+ abstract login(options: LoginOptions | TokenLoginOptions, operationOptions?: ClientOperationOptions): Promise<LoginResult>;
218
367
  abstract connect(serverName: string, loginResult: LoginResult, options?: ConnectOptions): Promise<Socket>;
219
368
  abstract disconnect(): void;
220
369
  abstract send(action: string, args: Record<string, unknown>): void;
370
+ protected connectionTimeouts(options?: ConnectOptions): ClientConnectionTimeouts;
371
+ protected reportLifecycle(options: ConnectOptions | undefined, phase: ClientLifecyclePhase, queue?: QueueUpdate): void;
372
+ protected resetLoginState(): void;
373
+ protected unsupportedOperation(operation: string): ClientOperationError;
221
374
  protected socketIoOptions(defaultUrlOrOrigin: string): SocketIoConnectionOptions;
222
375
  protected webSocketOptions(defaultUrlOrOrigin: string): {
223
376
  headers?: Record<string, string>;
@@ -250,6 +403,7 @@ declare abstract class BaseAdapter {
250
403
  buddyReject(_id: number): void;
251
404
  buddyRequestSeen(_id: number): void;
252
405
  getBuddy(_id: number, _type: "buddies" | "buddyRequests"): void;
406
+ findBuddy(_id: number): void;
253
407
  removeBuddy(_id: number): void;
254
408
  addIgnore(_id: number): void;
255
409
  removeIgnore(_id: number): void;
@@ -261,11 +415,48 @@ declare abstract class BaseAdapter {
261
415
  getPostcards(): void;
262
416
  getIglooOpen(_igloo: number): void;
263
417
  getIgloos(): void;
264
- getPuffles(_userId: number): void;
418
+ getPuffles(_userId: number, _isBackyard?: boolean): void;
419
+ getAllPuffles(): void;
420
+ getPuffleWellbeing(_puffle: number): void;
421
+ playPuffle(_puffle: number): void;
422
+ restPuffle(_puffle: number): void;
423
+ buyPuffleItem(_puffleId: number, _item: number): void;
424
+ walkPuffle(_puffle: number): void;
425
+ initializePuffleTower(): void;
426
+ getBackyardSupplies(): void;
265
427
  adoptPuffle(_type: number, _name: string): void;
266
428
  getIglooLikes(): void;
267
429
  checkPuffleSprite(_puffleSprite: boolean): void;
268
430
  joinIgloo(_igloo: number, _x?: number, _y?: number): void;
431
+ getStoreMusic(): void;
432
+ buyMusic(_music: string): void;
433
+ getIglooStoreItems(): void;
434
+ buyFurniture(_furniture: string, _amount: number): void;
435
+ updateIglooMusic(_music: string): void;
436
+ updateIglooFurniture(_furniture: Array<{
437
+ furnitureId: number;
438
+ x: number;
439
+ y: number;
440
+ rotation: number;
441
+ frame: number;
442
+ depth: number;
443
+ slot?: number;
444
+ }>): void;
445
+ autoUpdateIglooFurniture(_furniture: Array<{
446
+ furnitureId: number;
447
+ x: number;
448
+ y: number;
449
+ rotation: number;
450
+ frame: number;
451
+ depth: number;
452
+ slot?: number;
453
+ }>): void;
454
+ updateIglooType(_type: number): void;
455
+ openIgloo(): void;
456
+ closeIglooBounds(): void;
457
+ likeIgloo(): void;
458
+ openIglooEditor(): void;
459
+ closeIglooEditor(): void;
269
460
  gameOver(_coins: number): void;
270
461
  collectStamp(_stamp: number): void;
271
462
  /** Fetch ninja rank, progress, and card deck. Listen for `get_ninja` event. */
@@ -288,7 +479,8 @@ declare abstract class BaseAdapter {
288
479
 
289
480
  declare class CpjourneyAdapter extends BaseAdapter {
290
481
  readonly id = "CPJourney";
291
- login(options: LoginOptions | TokenLoginOptions): Promise<LoginResult>;
482
+ private gameToken;
483
+ login(options: LoginOptions | TokenLoginOptions, operationOptions?: ClientOperationOptions): Promise<LoginResult>;
292
484
  connect(serverName: string, loginResult: LoginResult, options?: ConnectOptions): Promise<Socket>;
293
485
  private queueForServer;
294
486
  send(action: string, args: Record<string, unknown>): void;
@@ -317,6 +509,7 @@ declare class CpjourneyAdapter extends BaseAdapter {
317
509
  buddyReject(id: number): void;
318
510
  buddyRequestSeen(id: number): void;
319
511
  getBuddy(id: number, type: "buddies" | "buddyRequests"): void;
512
+ findBuddy(id: number): void;
320
513
  removeBuddy(id: number): void;
321
514
  addIgnore(id: number): void;
322
515
  removeIgnore(id: number): void;
@@ -328,11 +521,48 @@ declare class CpjourneyAdapter extends BaseAdapter {
328
521
  getPostcards(): void;
329
522
  getIglooOpen(igloo: number): void;
330
523
  getIgloos(): void;
331
- getPuffles(userId: number): void;
524
+ getPuffles(userId: number, isBackyard?: boolean): void;
525
+ getAllPuffles(): void;
526
+ getPuffleWellbeing(puffle: number): void;
527
+ playPuffle(puffle: number): void;
528
+ restPuffle(puffle: number): void;
529
+ buyPuffleItem(puffleId: number, item: number): void;
530
+ walkPuffle(puffle: number): void;
531
+ initializePuffleTower(): void;
532
+ getBackyardSupplies(): void;
332
533
  adoptPuffle(type: number, name: string): void;
333
534
  getIglooLikes(): void;
334
535
  checkPuffleSprite(puffleSprite: boolean): void;
335
536
  joinIgloo(igloo: number, x?: number, y?: number): void;
537
+ getStoreMusic(): void;
538
+ buyMusic(music: string): void;
539
+ getIglooStoreItems(): void;
540
+ buyFurniture(furniture: string, amount: number): void;
541
+ updateIglooMusic(music: string): void;
542
+ updateIglooFurniture(furniture: Array<{
543
+ furnitureId: number;
544
+ x: number;
545
+ y: number;
546
+ rotation: number;
547
+ frame: number;
548
+ depth: number;
549
+ slot?: number;
550
+ }>): void;
551
+ autoUpdateIglooFurniture(furniture: Array<{
552
+ furnitureId: number;
553
+ x: number;
554
+ y: number;
555
+ rotation: number;
556
+ frame: number;
557
+ depth: number;
558
+ slot?: number;
559
+ }>): void;
560
+ updateIglooType(type: number): void;
561
+ openIgloo(): void;
562
+ closeIglooBounds(): void;
563
+ likeIgloo(): void;
564
+ openIglooEditor(): void;
565
+ closeIglooEditor(): void;
336
566
  gameOver(coins: number): void;
337
567
  collectStamp(stamp: number): void;
338
568
  getNinja(): void;
@@ -343,13 +573,13 @@ declare class CpjourneyAdapter extends BaseAdapter {
343
573
  selectCard(slot: number): void;
344
574
  loadAnimation(animation: string): void;
345
575
  joinMat(waddle: number): void;
346
- private createSocket;
576
+ protected createSocket(path: string): Socket;
347
577
  }
348
578
 
349
579
  declare class CplegacyAdapter extends BaseAdapter {
350
580
  readonly id = "CPLegacy";
351
581
  private version;
352
- login(options: LoginOptions | TokenLoginOptions): Promise<LoginResult>;
582
+ login(options: LoginOptions | TokenLoginOptions, operationOptions?: ClientOperationOptions): Promise<LoginResult>;
353
583
  connect(serverName: string, loginResult: LoginResult, options?: ConnectOptions): Promise<Socket>;
354
584
  send(action: string, args: Record<string, unknown>): void;
355
585
  disconnect(): void;
@@ -385,13 +615,15 @@ declare class CplegacyAdapter extends BaseAdapter {
385
615
  gameOver(coins: number): void;
386
616
  collectStamp(stamp: number): void;
387
617
  private postLogin;
618
+ protected createSocket(serverName: string): Socket;
388
619
  }
389
620
 
390
- declare class CpzeroAdapter extends BaseAdapter {
391
- readonly id = "CPZero";
392
- private sfs;
393
- login(options: LoginOptions | TokenLoginOptions): Promise<LoginResult>;
394
- connect(_serverName: string, loginResult: LoginResult, _options?: ConnectOptions): Promise<socket_io_client.Socket>;
621
+ declare class CppslolAdapter extends BaseAdapter {
622
+ readonly id = "CPPS.lol";
623
+ private signer;
624
+ private sessionToken;
625
+ login(options: LoginOptions | TokenLoginOptions, operationOptions?: ClientOperationOptions): Promise<LoginResult>;
626
+ connect(serverName: string, loginResult: LoginResult, options?: ConnectOptions): Promise<Socket>;
395
627
  send(action: string, args: Record<string, unknown>): void;
396
628
  disconnect(): void;
397
629
  normalizeUser(raw: Record<string, unknown>): RoomUser;
@@ -400,10 +632,11 @@ declare class CpzeroAdapter extends BaseAdapter {
400
632
  sendEmote(emote: number): void;
401
633
  sendSafe(safe: number): void;
402
634
  walk(x: number, y: number): void;
403
- sendFrame(frame: number): void;
635
+ sendFrame(frame: number, set?: boolean): void;
404
636
  snowball(x: number, y: number): void;
405
637
  joinRoom(room: number, x?: number, y?: number): void;
406
638
  addItem(item: number): void;
639
+ private updatePlayer;
407
640
  equipColor(item: number): void;
408
641
  equipHead(item: number): void;
409
642
  equipFace(item: number): void;
@@ -413,20 +646,30 @@ declare class CpzeroAdapter extends BaseAdapter {
413
646
  equipFeet(item: number): void;
414
647
  equipFlag(item: number): void;
415
648
  equipPhoto(item: number): void;
416
- getPlayer(id: number): void;
417
- joinIgloo(igloo: number, _x?: number, _y?: number): void;
418
- /**
419
- * Process a batch of `%xt%` messages that may be concatenated in a single
420
- * WebSocket frame (separated by \0 already split, but multiple %xt% in one string).
421
- */
422
- private processXtBatch;
649
+ getIglooOpen(igloo: number): void;
650
+ joinIgloo(igloo: number, x?: number, y?: number): void;
651
+ updateIglooFurniture(furniture: IglooFurniturePlacement[]): void;
652
+ openIglooRaw(): void;
653
+ sendPackedEmote(pack: number, emote: number): void;
654
+ updateLayeredPlayer(item: number): void;
655
+ acceptMature(): void;
656
+ removeInventory(item: number): void;
657
+ getSnowflakeState(): void;
658
+ getPets(userId: number): void;
659
+ getIglooContest(): void;
660
+ getIglooLikesFor(iglooId: number): void;
661
+ likeIglooById(iglooId: number): void;
662
+ sendMail(recipient: number, postcardId: number): void;
663
+ marryRequest(id: number): void;
664
+ leaveWaddle(): void;
665
+ protected createSocket(path: string): Socket;
423
666
  }
424
667
 
425
668
  declare class NewcpAdapter extends BaseAdapter {
426
669
  readonly id = "NewCP";
427
670
  private encryptor;
428
671
  private worlds;
429
- login(options: LoginOptions | TokenLoginOptions): Promise<LoginResult>;
672
+ login(options: LoginOptions | TokenLoginOptions, operationOptions?: ClientOperationOptions): Promise<LoginResult>;
430
673
  connect(serverName: string, loginResult: LoginResult, options?: ConnectOptions): Promise<Socket>;
431
674
  send(action: string, args: Record<string, unknown>): void;
432
675
  disconnect(): void;
@@ -457,13 +700,13 @@ declare class NewcpAdapter extends BaseAdapter {
457
700
  removeIgnore(id: number): void;
458
701
  getPlayer(id: number): void;
459
702
  joinIgloo(igloo: number, x?: number, y?: number): void;
460
- private createSocket;
703
+ protected createSocket(host: string, path: string): Socket;
461
704
  private loadWorlds;
462
705
  }
463
706
 
464
707
  declare class PenguinoriginsAdapter extends BaseAdapter {
465
708
  readonly id = "PenguinOrigins";
466
- login(options: LoginOptions | TokenLoginOptions): Promise<LoginResult>;
709
+ login(options: LoginOptions | TokenLoginOptions, operationOptions?: ClientOperationOptions): Promise<LoginResult>;
467
710
  connect(serverName: string, loginResult: LoginResult, options?: ConnectOptions): Promise<Socket>;
468
711
  send(action: string, args: Record<string, unknown>): void;
469
712
  disconnect(): void;
@@ -493,13 +736,13 @@ declare class PenguinoriginsAdapter extends BaseAdapter {
493
736
  getIglooOpen(igloo: number): void;
494
737
  joinIgloo(igloo: number, x?: number, y?: number): void;
495
738
  gameOver(coins: number): void;
496
- private createSocket;
739
+ protected createSocket(path: string): Socket;
497
740
  }
498
741
 
499
742
  declare const ADAPTERS: {
743
+ readonly CPPSlol: typeof CppslolAdapter;
500
744
  readonly CPJourney: typeof CpjourneyAdapter;
501
745
  readonly CPLegacy: typeof CplegacyAdapter;
502
- readonly CPZero: typeof CpzeroAdapter;
503
746
  readonly NewCP: typeof NewcpAdapter;
504
747
  readonly PenguinOrigins: typeof PenguinoriginsAdapter;
505
748
  };
@@ -523,10 +766,11 @@ type ClientMessages = {
523
766
  y?: number;
524
767
  };
525
768
  add_item: {
526
- item: number;
769
+ item: number | string;
527
770
  };
528
771
  send_emote: {
529
772
  emote: number;
773
+ pack?: number;
530
774
  };
531
775
  send_safe: {
532
776
  safe: number;
@@ -577,8 +821,11 @@ type ClientMessages = {
577
821
  get_igloos: Record<string, never>;
578
822
  get_puffles: {
579
823
  userId: number;
824
+ isBackyard?: boolean;
825
+ };
826
+ get_igloo_likes: {
827
+ iglooId?: number;
580
828
  };
581
- get_igloo_likes: Record<string, never>;
582
829
  join_igloo: {
583
830
  igloo: number;
584
831
  x?: number;
@@ -628,6 +875,56 @@ type ClientMessages = {
628
875
  check_puffle_sprite: {
629
876
  puffleSprite: unknown;
630
877
  };
878
+ get_all_puffles: Record<string, never>;
879
+ get_wellbeing: {
880
+ puffle: number;
881
+ };
882
+ puffle_play: {
883
+ puffle: number;
884
+ };
885
+ update_puffle_rest: {
886
+ puffle: number;
887
+ };
888
+ puffle_buy_item: {
889
+ puffleId: number;
890
+ item: number;
891
+ };
892
+ walk_puffle: {
893
+ puffle: number;
894
+ };
895
+ backyard_supplies: Record<string, never>;
896
+ buddy_find: {
897
+ id: number;
898
+ };
899
+ get_store_music: Record<string, never>;
900
+ add_music: {
901
+ music: string;
902
+ };
903
+ get_igloostore_items: Record<string, never>;
904
+ add_furniture: {
905
+ furniture: string;
906
+ amount: number;
907
+ };
908
+ update_music: {
909
+ music: string;
910
+ };
911
+ update_furniture: {
912
+ furniture: IglooFurniturePlacement[];
913
+ };
914
+ update_furniture_auto: {
915
+ furniture: IglooFurniturePlacement[];
916
+ };
917
+ update_igloo: {
918
+ type: number;
919
+ };
920
+ open_igloo: Record<string, never>;
921
+ close_igloo_bounds: Record<string, never>;
922
+ like_igloo: {
923
+ iglooId?: number;
924
+ };
925
+ igloo_editor_open: Record<string, never>;
926
+ igloo_editor_closed: Record<string, never>;
927
+ tower_init: Record<string, never>;
631
928
  queue_server_join: {
632
929
  server: string;
633
930
  };
@@ -653,6 +950,24 @@ type ClientMessages = {
653
950
  join_waddle: {
654
951
  waddle: number;
655
952
  };
953
+ /** CPPS.lol-only packets. */
954
+ leave_waddle: Record<string, never>;
955
+ remove_inventory: {
956
+ item: number;
957
+ };
958
+ get_snowflake_state: Record<string, never>;
959
+ accept_mature: Record<string, never>;
960
+ get_pets: {
961
+ userId: number;
962
+ };
963
+ get_igloo_contest: Record<string, never>;
964
+ send_mail: {
965
+ recipient: number;
966
+ postcardId: number;
967
+ };
968
+ marry_request: {
969
+ id: number;
970
+ };
656
971
  };
657
972
  type ServerMessages = {
658
973
  login: {
@@ -697,6 +1012,7 @@ type ServerMessages = {
697
1012
  send_emote: {
698
1013
  id: number;
699
1014
  emote: number;
1015
+ pack?: number;
700
1016
  };
701
1017
  join_game_room: {
702
1018
  game: number;
@@ -788,8 +1104,10 @@ type ServerMessages = {
788
1104
  id: number;
789
1105
  };
790
1106
  add_item: {
791
- item: number;
1107
+ item: number | string;
792
1108
  coins: number;
1109
+ name?: string;
1110
+ slot?: string;
793
1111
  };
794
1112
  get_postcards: {
795
1113
  postcards: Postcard[];
@@ -827,11 +1145,74 @@ type ServerMessages = {
827
1145
  };
828
1146
  get_puffles: {
829
1147
  userId: number;
830
- puffles: {
831
- id: number;
832
- type: number;
833
- }[];
1148
+ puffles: Puffle[];
1149
+ };
1150
+ get_all_puffles: {
1151
+ puffles: Puffle[];
1152
+ };
1153
+ get_wellbeing: PuffleWellbeing;
1154
+ get_walking_puffle: {
1155
+ puffle: Puffle;
1156
+ };
1157
+ update_wellbeing: PuffleWellbeing;
1158
+ puffle_levelup: {
1159
+ puffleId: number;
1160
+ level: number;
1161
+ };
1162
+ puffle_popup: {
1163
+ puffleId: number;
1164
+ popupId: number;
1165
+ };
1166
+ buy_puffle_item: {
1167
+ puffleId: number;
1168
+ item: number;
1169
+ coins: number;
1170
+ puffleInventory: Record<string, unknown>;
1171
+ };
1172
+ walk_puffle: {
1173
+ user: number;
1174
+ puffle: number;
1175
+ type: number;
1176
+ };
1177
+ backyard_supplies: {
1178
+ supplyCost: number;
1179
+ puffleCount: number;
1180
+ supplyState: number;
1181
+ };
1182
+ buddy_find: {
1183
+ find: number;
1184
+ username: string;
1185
+ game: boolean;
1186
+ };
1187
+ receive_postcard: Postcard;
1188
+ get_store_music: {
1189
+ music: IglooStoreItem[];
1190
+ };
1191
+ add_music: {
1192
+ music: string;
1193
+ coins: number;
1194
+ };
1195
+ get_igloostore_items: {
1196
+ furniture: FurnitureStoreItem[];
1197
+ flooring: IglooStoreItem[];
1198
+ igloo: IglooStoreItem[];
1199
+ location: IglooStoreItem[];
1200
+ };
1201
+ add_furniture: {
1202
+ furniture: string;
1203
+ coins: number;
1204
+ amount: number;
834
1205
  };
1206
+ update_music: {
1207
+ music: string;
1208
+ };
1209
+ igloo_open_status: {
1210
+ status: number;
1211
+ };
1212
+ igloo_bounds_status: {
1213
+ status: number;
1214
+ };
1215
+ igloo_liked: Record<string, never>;
835
1216
  update_player: {
836
1217
  id: number;
837
1218
  item: number;
@@ -878,7 +1259,7 @@ type ServerMessages = {
878
1259
  transform: number;
879
1260
  };
880
1261
  adopt_puffle: {
881
- puffle: unknown;
1262
+ puffle?: unknown;
882
1263
  coins: number;
883
1264
  };
884
1265
  /** Generic server info/notification message */
@@ -889,7 +1270,7 @@ type ServerMessages = {
889
1270
  action: string;
890
1271
  args: Record<string, unknown>;
891
1272
  };
892
- disconnect: undefined;
1273
+ disconnect: ClientDisconnectInfo;
893
1274
  /** Ninja rank, progress, and full card deck */
894
1275
  get_ninja: NinjaData;
895
1276
  /** State of all Dojo mats — keys are mat IDs, values are seat arrays */
@@ -953,31 +1334,90 @@ type ServerMessages = {
953
1334
  uuid: string[];
954
1335
  message: string;
955
1336
  };
1337
+ /** CPPS.lol-only events. */
1338
+ remove_inventory: {
1339
+ id: number | string;
1340
+ };
1341
+ snowflake_state: {
1342
+ windowOpen: boolean;
1343
+ lifetimeMs: number;
1344
+ type: string | number | null;
1345
+ };
1346
+ get_pets: {
1347
+ userId?: number;
1348
+ pets: Puffle[];
1349
+ };
1350
+ igloo_contest: {
1351
+ active: boolean;
1352
+ };
1353
+ igloo_likes: {
1354
+ iglooId: number;
1355
+ likes: number;
1356
+ liked: boolean;
1357
+ created?: boolean | string;
1358
+ };
1359
+ marry_request: {
1360
+ id: number;
1361
+ };
956
1362
  };
1363
+ /** CPPS.lol-only commands captured from its signed Socket.IO protocol. */
1364
+ type CppslolClientMessages = Pick<ClientMessages, "leave_waddle" | "remove_inventory" | "get_snowflake_state" | "accept_mature" | "get_pets" | "get_igloo_contest" | "send_mail" | "marry_request">;
1365
+ /** CPPS.lol-only events captured from its signed Socket.IO protocol. */
1366
+ type CppslolServerMessages = Pick<ServerMessages, "remove_inventory" | "snowflake_state" | "get_pets" | "igloo_contest" | "igloo_likes" | "marry_request">;
1367
+ /** CPJourney-only commands captured from its Socket.IO protocol. */
1368
+ type CpjourneyClientMessages = Pick<ClientMessages, "get_puffles" | "adopt_puffle" | "check_puffle_sprite" | "get_all_puffles" | "get_wellbeing" | "puffle_play" | "update_puffle_rest" | "puffle_buy_item" | "walk_puffle" | "backyard_supplies" | "buddy_find" | "get_store_music" | "add_music" | "get_igloostore_items" | "add_furniture" | "update_music" | "update_furniture" | "update_furniture_auto" | "update_igloo" | "open_igloo" | "close_igloo_bounds" | "like_igloo" | "igloo_editor_open" | "igloo_editor_closed" | "tower_init">;
1369
+ /** CPJourney-only events captured from its Socket.IO protocol. */
1370
+ type CpjourneyServerMessages = Pick<ServerMessages, "game_over" | "get_postcards" | "join_igloo" | "get_puffles" | "adopt_puffle" | "get_all_puffles" | "get_wellbeing" | "get_walking_puffle" | "update_wellbeing" | "puffle_levelup" | "puffle_popup" | "buy_puffle_item" | "walk_puffle" | "backyard_supplies" | "buddy_find" | "receive_postcard" | "get_store_music" | "add_music" | "get_igloostore_items" | "add_furniture" | "update_music" | "igloo_open_status" | "igloo_bounds_status" | "igloo_liked">;
957
1371
 
958
- type WaitForFn = <K extends keyof ServerMessages>(event: K, timeout?: number) => Promise<ServerMessages[K]>;
1372
+ type RequestFn$1 = <K extends keyof ServerMessages>(event: K, send: () => void, options?: ClientOperationOptions, matches?: (args: ServerMessages[K]) => boolean) => Promise<ServerMessages[K]>;
959
1373
  declare class CardJitsu {
960
1374
  private adapter;
961
- private waitFor;
962
- constructor(adapter: BaseAdapter, waitFor: WaitForFn);
1375
+ private request;
1376
+ constructor(adapter: BaseAdapter, request: RequestFn$1);
963
1377
  /** Fetch ninja rank, progress, and card deck. Resolves with ninja data. */
964
- getNinja(): Promise<ServerMessages["get_ninja"]>;
1378
+ getNinja(options?: ClientOperationOptions): Promise<ServerMessages["get_ninja"]>;
965
1379
  /** Fetch state of all Dojo mats. Resolves with mat state. */
966
- getMats(): Promise<ServerMessages["get_waddles"]>;
1380
+ getMats(options?: ClientOperationOptions): Promise<ServerMessages["get_waddles"]>;
967
1381
  /** Sit on a Dojo mat to wait for an opponent. Listen for `update_waddle` events. */
968
1382
  joinMat(waddle: number): void;
969
1383
  /** Join Sensei matchmaking queue. Resolves when server acknowledges. */
970
- joinMatchmaking(): Promise<ServerMessages["join_matchmaking"]>;
1384
+ joinMatchmaking(options?: ClientOperationOptions): Promise<ServerMessages["join_matchmaking"]>;
971
1385
  /** Leave Sensei matchmaking queue. */
972
1386
  leaveMatchmaking(): void;
973
1387
  /** Start a Card-Jitsu match after entering a game room. Resolves with player info. */
974
- startGame(): Promise<ServerMessages["start_game"]>;
1388
+ startGame(options?: ClientOperationOptions): Promise<ServerMessages["start_game"]>;
975
1389
  /** Play a card from your hand by slot index. Resolves when server acknowledges. */
976
- selectCard(slot: number): Promise<ServerMessages["move_my_card"]>;
1390
+ selectCard(slot: number, options?: ClientOperationOptions): Promise<ServerMessages["move_my_card"]>;
977
1391
  /** Preload a power card animation asset. */
978
1392
  loadAnimation(animation: string): void;
979
1393
  }
980
1394
 
1395
+ type RequestFn = <K extends keyof ServerMessages>(event: K, send: () => void, options?: ClientOperationOptions, matches?: (args: ServerMessages[K]) => boolean) => Promise<ServerMessages[K]>;
1396
+ /** Operations implemented only by CPPS.lol's captured protocol. */
1397
+ declare class Cppslol {
1398
+ private readonly baseAdapter;
1399
+ private readonly request;
1400
+ constructor(baseAdapter: BaseAdapter, request: RequestFn);
1401
+ private get adapter();
1402
+ /** Send an emote from a CPPS.lol emote pack. */
1403
+ sendPackedEmote(pack: number, emote: number): void;
1404
+ /** Equip an item in CPPS.lol's additional appearance layer. */
1405
+ updateLayeredPlayer(item: number): void;
1406
+ /** Acknowledge the mature-server notice for the current session. */
1407
+ acceptMature(): void;
1408
+ removeInventory(item: number, options?: ClientOperationOptions): Promise<ServerMessages["remove_inventory"]>;
1409
+ getSnowflakeState(options?: ClientOperationOptions): Promise<ServerMessages["snowflake_state"]>;
1410
+ getPets(userId: number, options?: ClientOperationOptions): Promise<ServerMessages["get_pets"]>;
1411
+ getIglooContest(options?: ClientOperationOptions): Promise<ServerMessages["igloo_contest"]>;
1412
+ getIglooLikes(iglooId: number, options?: ClientOperationOptions): Promise<ServerMessages["igloo_likes"]>;
1413
+ likeIgloo(iglooId: number, options?: ClientOperationOptions): Promise<ServerMessages["igloo_likes"]>;
1414
+ /** CPPS.lol does not acknowledge this action with a dedicated response. */
1415
+ openIgloo(): void;
1416
+ sendMail(recipient: number, postcardId: number): void;
1417
+ marryRequest(id: number): void;
1418
+ leaveWaddle(): void;
1419
+ }
1420
+
981
1421
  type ServerMessageHandler<K extends keyof ServerMessages> = (args: ServerMessages[K]) => void;
982
1422
  type LogFn = (message: string, ...args: unknown[]) => void;
983
1423
  type ClientOptions = {
@@ -993,12 +1433,22 @@ declare class Client extends EventEmitter {
993
1433
  private loginResult;
994
1434
  private log;
995
1435
  private _cardJitsu;
1436
+ private _cppslol;
1437
+ private intentionalDisconnect;
1438
+ private disconnectNotified;
1439
+ private connectionFailure;
1440
+ private lifecycleReporter;
1441
+ private requestTails;
1442
+ private disconnectEpoch;
1443
+ private lastDisconnectInfo;
996
1444
  get loginMessage(): string | null;
997
1445
  get loginStatus(): "active" | "banned";
998
1446
  get cardJitsu(): CardJitsu;
1447
+ get cppslol(): Cppslol;
999
1448
  constructor(server: AdapterName, options?: ClientOptions);
1000
- login(options: LoginOptions | TokenLoginOptions): Promise<ServerInfo[]>;
1449
+ login(options: LoginOptions | TokenLoginOptions, operationOptions?: ClientOperationOptions): Promise<ServerInfo[]>;
1001
1450
  connect(serverName: string, options?: ConnectOptions): Promise<void>;
1451
+ private waitForInitialState;
1002
1452
  on<K extends keyof ServerMessages>(event: K, listener: ServerMessageHandler<K>): this;
1003
1453
  on(event: string, listener: (...args: unknown[]) => void): this;
1004
1454
  off<K extends keyof ServerMessages>(event: K, listener: ServerMessageHandler<K>): this;
@@ -1007,16 +1457,20 @@ declare class Client extends EventEmitter {
1007
1457
  once(event: string, listener: (...args: unknown[]) => void): this;
1008
1458
  emit<K extends keyof ServerMessages>(event: K, args: ServerMessages[K]): boolean;
1009
1459
  emit(event: string, ...args: unknown[]): boolean;
1010
- /** Wait for a server event. Resolves with the event payload. Optional timeout in ms. Rejects on disconnect. */
1460
+ /** Wait for a server event. Resolves with the event payload and rejects on timeout, abort, or disconnect. */
1011
1461
  waitFor<K extends keyof ServerMessages>(event: K, timeout?: number): Promise<ServerMessages[K]>;
1462
+ waitFor<K extends keyof ServerMessages>(event: K, options?: ClientOperationOptions): Promise<ServerMessages[K]>;
1463
+ private waitForEvent;
1464
+ private request;
1465
+ private waitForRequestTurn;
1012
1466
  sendMessage(message: string): void;
1013
1467
  sendEmote(emote: number): void;
1014
1468
  sendSafe(safe: number): void;
1015
1469
  walk(x: number, y: number): void;
1016
1470
  sendFrame(frame: number, set?: boolean): void;
1017
1471
  snowball(x: number, y: number): void;
1018
- joinRoom(room: number, x?: number, y?: number): Promise<ServerMessages["join_room"]>;
1019
- addItem(item: number): Promise<ServerMessages["add_item"]>;
1472
+ joinRoom(room: number, x?: number, y?: number, options?: ClientOperationOptions): Promise<ServerMessages["join_room"]>;
1473
+ addItem(item: number, options?: ClientOperationOptions): Promise<ServerMessages["add_item"]>;
1020
1474
  equipColor(item: number): void;
1021
1475
  equipHead(item: number): void;
1022
1476
  equipFace(item: number): void;
@@ -1027,32 +1481,59 @@ declare class Client extends EventEmitter {
1027
1481
  equipFlag(item: number): void;
1028
1482
  equipPhoto(item: number): void;
1029
1483
  buddyRequest(id: number): void;
1030
- buddyAccept(id: number): Promise<ServerMessages["buddy_accept"]>;
1031
- buddyReject(id: number): Promise<ServerMessages["buddy_reject"]>;
1032
- buddyRequestSeen(id: number): Promise<ServerMessages["buddy_request_seen"]>;
1033
- getBuddy(id: number, type: "buddies" | "buddyRequests"): Promise<ServerMessages["get_buddy"]>;
1484
+ buddyAccept(id: number, options?: ClientOperationOptions): Promise<ServerMessages["buddy_accept"]>;
1485
+ buddyReject(id: number, options?: ClientOperationOptions): Promise<ServerMessages["buddy_reject"]>;
1486
+ buddyRequestSeen(id: number, options?: ClientOperationOptions): Promise<ServerMessages["buddy_request_seen"]>;
1487
+ getBuddy(id: number, type: "buddies" | "buddyRequests", options?: ClientOperationOptions): Promise<ServerMessages["get_buddy"]>;
1488
+ findBuddy(id: number, options?: ClientOperationOptions): Promise<ServerMessages["buddy_find"]>;
1034
1489
  removeBuddy(id: number): void;
1035
- addIgnore(id: number): Promise<ServerMessages["ignore_add"]>;
1036
- removeIgnore(id: number): Promise<ServerMessages["ignore_remove"]>;
1037
- getPlayer(id: number): Promise<ServerMessages["get_player"]>;
1038
- getAllSlots(): Promise<ServerMessages["slot"]>;
1039
- getMascots(): Promise<ServerMessages["get_mascots"]>;
1040
- sendPostcard(userId: number, cardId: string): Promise<ServerMessages["send_postcard"]>;
1041
- getStamps(userId: number): Promise<ServerMessages["stamps_result"]>;
1042
- getPostcards(): Promise<ServerMessages["get_postcards"]>;
1043
- getIglooOpen(igloo: number): Promise<ServerMessages["get_igloo_open"]>;
1044
- getIgloos(): Promise<ServerMessages["get_igloos"]>;
1045
- getPuffles(userId: number): Promise<ServerMessages["get_puffles"]>;
1046
- adoptPuffle(type: number, name: string): Promise<ServerMessages["adopt_puffle"]>;
1047
- getIglooLikes(): Promise<ServerMessages["get_igloo_likes"]>;
1490
+ addIgnore(id: number, options?: ClientOperationOptions): Promise<ServerMessages["ignore_add"]>;
1491
+ removeIgnore(id: number, options?: ClientOperationOptions): Promise<ServerMessages["ignore_remove"]>;
1492
+ getPlayer(id: number, options?: ClientOperationOptions): Promise<ServerMessages["get_player"]>;
1493
+ getAllSlots(options?: ClientOperationOptions): Promise<ServerMessages["slot"]>;
1494
+ getMascots(options?: ClientOperationOptions): Promise<ServerMessages["get_mascots"]>;
1495
+ sendPostcard(userId: number, cardId: string, options?: ClientOperationOptions): Promise<ServerMessages["send_postcard"]>;
1496
+ getStamps(userId: number, options?: ClientOperationOptions): Promise<ServerMessages["stamps_result"]>;
1497
+ getPostcards(options?: ClientOperationOptions): Promise<ServerMessages["get_postcards"]>;
1498
+ getIglooOpen(igloo: number, options?: ClientOperationOptions): Promise<ServerMessages["get_igloo_open"]>;
1499
+ getIgloos(options?: ClientOperationOptions): Promise<ServerMessages["get_igloos"]>;
1500
+ getPuffles(userId: number, options?: ClientOperationOptions & {
1501
+ isBackyard?: boolean;
1502
+ }): Promise<ServerMessages["get_puffles"]>;
1503
+ getAllPuffles(options?: ClientOperationOptions): Promise<ServerMessages["get_all_puffles"]>;
1504
+ getPuffleWellbeing(puffle: number, options?: ClientOperationOptions): Promise<ServerMessages["get_wellbeing"]>;
1505
+ playPuffle(puffle: number): void;
1506
+ restPuffle(puffle: number): void;
1507
+ buyPuffleItem(puffleId: number, item: number, options?: ClientOperationOptions): Promise<ServerMessages["buy_puffle_item"]>;
1508
+ walkPuffle(puffle: number, options?: ClientOperationOptions): Promise<ServerMessages["get_walking_puffle"]>;
1509
+ /** CPJourney sends tower_init after its walking-puffle acknowledgement. */
1510
+ initializePuffleTower(): void;
1511
+ getBackyardSupplies(options?: ClientOperationOptions): Promise<ServerMessages["backyard_supplies"]>;
1512
+ adoptPuffle(type: number, name: string, options?: ClientOperationOptions): Promise<ServerMessages["adopt_puffle"]>;
1513
+ getIglooLikes(options?: ClientOperationOptions): Promise<ServerMessages["get_igloo_likes"]>;
1048
1514
  checkPuffleSprite(puffleSprite: boolean): void;
1049
- joinIgloo(igloo: number, x?: number, y?: number): Promise<ServerMessages["join_igloo"]>;
1050
- gameOver(coins: number): Promise<ServerMessages["game_over"]>;
1051
- collectStamp(stamp: number): Promise<ServerMessages["stamp_earned"]>;
1515
+ joinIgloo(igloo: number, x?: number, y?: number, options?: ClientOperationOptions): Promise<ServerMessages["join_igloo"]>;
1516
+ getStoreMusic(options?: ClientOperationOptions): Promise<ServerMessages["get_store_music"]>;
1517
+ buyMusic(music: string, options?: ClientOperationOptions): Promise<ServerMessages["add_music"]>;
1518
+ getIglooStoreItems(options?: ClientOperationOptions): Promise<ServerMessages["get_igloostore_items"]>;
1519
+ buyFurniture(furniture: string, amount?: number, options?: ClientOperationOptions): Promise<ServerMessages["add_furniture"]>;
1520
+ updateIglooMusic(music: string, options?: ClientOperationOptions): Promise<ServerMessages["update_music"]>;
1521
+ updateIglooFurniture(furniture: ClientMessages["update_furniture"]["furniture"]): void;
1522
+ autoUpdateIglooFurniture(furniture: ClientMessages["update_furniture_auto"]["furniture"]): void;
1523
+ updateIglooType(type: number): void;
1524
+ openIgloo(options?: ClientOperationOptions): Promise<ServerMessages["igloo_open_status"]>;
1525
+ closeIglooBounds(options?: ClientOperationOptions): Promise<ServerMessages["igloo_bounds_status"]>;
1526
+ likeIgloo(options?: ClientOperationOptions): Promise<ServerMessages["igloo_liked"]>;
1527
+ openIglooEditor(): void;
1528
+ closeIglooEditor(): void;
1529
+ gameOver(coins: number, options?: ClientOperationOptions): Promise<ServerMessages["game_over"]>;
1530
+ collectStamp(stamp: number, options?: ClientOperationOptions): Promise<ServerMessages["stamp_earned"]>;
1052
1531
  sleep(ms: number): Promise<void>;
1053
1532
  disconnect(): void;
1533
+ private reportLifecycle;
1534
+ private handleAdapterDisconnect;
1054
1535
  private cleanup;
1055
1536
  private handleMessage;
1056
1537
  }
1057
1538
 
1058
- export { type AdapterName, BaseAdapter, type Buddy, CardJitsu, Client, type ClientMessages, type ClientOptions, type ConnectOptions, type ConnectionProfile, type ConnectionProfileInput, type ConnectionProfilePreset, type GameCard, type GamePlayer, type LogFn, type LoginOptions, type LoginResult, type Mascot, type MatState, type NinjaCard, type NinjaData, type NinjaProgress, type PlayerAppearance, type PlayerData, type PlayerSettings, type Postcard, type QueueUpdate, type RevealedCard, type RoomUser, type RoundResult, type ServerInfo, type ServerMessages, type TokenLoginOptions };
1539
+ export { type AdapterName, BaseAdapter, type Buddy, CardJitsu, Client, type ClientConnectionTimeouts, type ClientDisconnectInfo, type ClientLifecyclePhase, type ClientLifecycleUpdate, type ClientMessages, ClientOperationError, type ClientOperationErrorCategory, type ClientOperationErrorOptions, type ClientOperationOptions, type ClientOptions, type ConnectOptions, type ConnectionProfile, type ConnectionProfileInput, type ConnectionProfilePreset, type CpjourneyClientMessages, type CpjourneyServerMessages, Cppslol, type CppslolClientMessages, type CppslolServerMessages, DEFAULT_CLIENT_CONNECTION_TIMEOUTS, type FurnitureStoreItem, type GameCard, type GamePlayer, type IglooFurniturePlacement, type IglooStoreItem, type LogFn, type LoginOptions, type LoginResult, type Mascot, type MatState, type NinjaCard, type NinjaData, type NinjaProgress, type PlayerAppearance, type PlayerData, type PlayerSettings, type Postcard, type Puffle, type PuffleWellbeing, type QueueUpdate, type RevealedCard, type RoomUser, type RoundResult, type ServerInfo, type ServerMessages, type TokenLoginOptions, sanitizeClientErrorMessage };