@shaunlwm/pickle.ts 0.0.2 → 0.2.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/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Type-safe client library for Club Penguin Private Servers.
4
4
 
5
- Built with TypeScript, Socket.IO, and msgpack. Supports multiple CPPS backends through an adapter pattern — currently ships with CPJourney support.
5
+ Built with TypeScript, Socket.IO, and msgpack. Supports multiple CPPS backends through an adapter pattern — ships with CPJourney and CPLegacy support.
6
6
 
7
7
  ## Install
8
8
 
@@ -44,7 +44,7 @@ Creates a new client instance.
44
44
 
45
45
  | Param | Type | Description |
46
46
  |---|---|---|
47
- | `server` | `"CPJourney"` | CPPS server identifier (strongly typed) |
47
+ | `server` | `"CPJourney" \| "CPLegacy"` | CPPS server identifier (strongly typed) |
48
48
  | `options.debug` | `boolean \| LogFn` | Enable debug logging. Pass `true` for console.log, or a custom function |
49
49
 
50
50
  ```typescript
@@ -102,6 +102,7 @@ After `connect()` resolves, `client.player`, `client.room`, and `client.users` a
102
102
  | `client.player` | `PlayerData \| null` | Your penguin's full data (coins, inventory, settings, etc.) |
103
103
  | `client.room` | `number \| null` | Current room ID |
104
104
  | `client.users` | `Map<number, RoomUser>` | All penguins in the current room, keyed by ID |
105
+ | `client.connected` | `boolean` | Whether the client is connected to a game server |
105
106
 
106
107
  `client.users` is automatically kept in sync — players are added/removed as they join/leave, positions and equipment update in real-time.
107
108
 
@@ -134,10 +135,20 @@ client.addItem(itemId)
134
135
  // Social
135
136
  client.buddyRequest(userId)
136
137
  client.buddyAccept(userId)
138
+ client.buddyReject(userId)
139
+ client.buddyRequestSeen(userId)
140
+ client.getBuddy(userId, "buddies") // fetch buddy details
141
+ client.getBuddy(userId, "buddyRequests") // fetch request details
137
142
  client.removeBuddy(userId)
138
143
  client.addIgnore(userId)
139
144
  client.removeIgnore(userId)
140
145
  client.getPlayer(userId)
146
+ client.sendPostcard(userId, "62") // send mail (costs coins)
147
+
148
+ // Stamps & Igloos
149
+ client.getStamps(userId) // view stampbook
150
+ client.getIglooOpen(userId) // check if igloo is open
151
+ client.joinIgloo(userId) // enter igloo
141
152
 
142
153
  // Animation
143
154
  client.sendFrame(frameId)
@@ -191,11 +202,29 @@ client.on("wait_queue_update", ({ position, queueLength }) => {
191
202
  console.log(`Queue: #${position}/${queueLength}`)
192
203
  })
193
204
 
205
+ client.on("kick", ({ reason }) => {
206
+ console.log(`Kicked: ${reason}`)
207
+ })
208
+
209
+ client.on("close_with_error", ({ error }) => {
210
+ console.log(`Disconnected: ${error}`)
211
+ })
212
+
213
+ client.on("buddy_accept", ({ id, username, online }) => {
214
+ console.log(`${username} accepted your buddy request (online: ${online})`)
215
+ })
216
+
217
+ client.on("stamps_result", ({ stamps, username }) => {
218
+ console.log(`${username} has ${stamps.length} stamps`)
219
+ })
220
+
194
221
  client.on("disconnect", () => {
195
222
  console.log("Connection lost")
196
223
  })
197
224
  ```
198
225
 
226
+ The `kick` event fires on CPLegacy, `close_with_error` on CPJourney — both indicate the server forcibly disconnected the client (e.g. duplicate login). State is automatically cleaned up in both cases.
227
+
199
228
  ## Types
200
229
 
201
230
  All types are exported for external use:
package/dist/index.d.ts CHANGED
@@ -57,12 +57,22 @@ declare abstract class BaseAdapter {
57
57
  equipPhoto(item: number): void;
58
58
  buddyRequest(id: number): void;
59
59
  buddyAccept(id: number): void;
60
+ buddyReject(id: number): void;
61
+ buddyRequestSeen(id: number): void;
62
+ getBuddy(id: number, type: "buddies" | "buddyRequests"): void;
60
63
  removeBuddy(id: number): void;
61
64
  addIgnore(id: number): void;
62
65
  removeIgnore(id: number): void;
63
66
  getPlayer(id: number): void;
64
67
  getAllSlots(): void;
65
68
  getMascots(): void;
69
+ sendPostcard(userId: number, cardId: string): void;
70
+ getStamps(userId: number): void;
71
+ getPostcards(): void;
72
+ getIglooOpen(igloo: number): void;
73
+ joinIgloo(igloo: number, x?: number, y?: number): void;
74
+ gameOver(coins: number): void;
75
+ collectStamp(stamp: number): void;
66
76
  }
67
77
 
68
78
  declare class CpjourneyAdapter extends BaseAdapter {
@@ -74,8 +84,19 @@ declare class CpjourneyAdapter extends BaseAdapter {
74
84
  private createSocket;
75
85
  }
76
86
 
87
+ declare class CplegacyAdapter extends BaseAdapter {
88
+ readonly id = "CPLegacy";
89
+ private version;
90
+ login(options: LoginOptions | TokenLoginOptions): Promise<LoginResult>;
91
+ connect(serverName: string, loginResult: LoginResult, options?: ConnectOptions): Promise<Socket>;
92
+ send(action: string, args: Record<string, unknown>): void;
93
+ disconnect(): void;
94
+ private postLogin;
95
+ }
96
+
77
97
  declare const ADAPTERS: {
78
98
  readonly CPJourney: typeof CpjourneyAdapter;
99
+ readonly CPLegacy: typeof CplegacyAdapter;
79
100
  };
80
101
  type AdapterName = keyof typeof ADAPTERS;
81
102
 
@@ -157,6 +178,14 @@ type PlayerData = RoomUser & {
157
178
  towerMeters: number;
158
179
  towerExperience: number;
159
180
  };
181
+ type Postcard = {
182
+ id: number;
183
+ username: string;
184
+ senderId: number;
185
+ postcardId: number;
186
+ extra: string | null;
187
+ date: string;
188
+ };
160
189
  type Mascot = {
161
190
  id: number;
162
191
  name: string;
@@ -200,18 +229,44 @@ type ClientMessages = {
200
229
  buddy_accept: {
201
230
  id: number;
202
231
  };
232
+ buddy_reject: {
233
+ id: number;
234
+ };
235
+ buddy_request_seen: {
236
+ id: number;
237
+ };
238
+ get_buddy: {
239
+ id: number;
240
+ type: "buddies" | "buddyRequests";
241
+ };
203
242
  remove_buddy: {
204
243
  id: number;
205
244
  };
206
245
  get_player: {
207
246
  id: number;
208
247
  };
209
- add_ignore: {
248
+ ignore_add: {
210
249
  id: number;
211
250
  };
212
- remove_ignore: {
251
+ ignore_remove: {
213
252
  id: number;
214
253
  };
254
+ send_postcard: {
255
+ userId: number;
256
+ cardId: string;
257
+ };
258
+ get_stamps: {
259
+ userId: number;
260
+ };
261
+ get_postcards: Record<string, never>;
262
+ get_igloo_open: {
263
+ igloo: number;
264
+ };
265
+ join_igloo: {
266
+ igloo: number;
267
+ x?: number;
268
+ y?: number;
269
+ };
215
270
  update_color: {
216
271
  item: number;
217
272
  };
@@ -239,6 +294,12 @@ type ClientMessages = {
239
294
  update_photo: {
240
295
  item: number;
241
296
  };
297
+ game_over: {
298
+ coins: number;
299
+ };
300
+ collect_stamp: {
301
+ stamp: number;
302
+ };
242
303
  get_all_slots: Record<string, never>;
243
304
  get_mascots: Record<string, never>;
244
305
  get_weather: Record<string, never>;
@@ -291,6 +352,23 @@ type ServerMessages = {
291
352
  id: number;
292
353
  emote: number;
293
354
  };
355
+ join_game_room: {
356
+ game: number;
357
+ };
358
+ game_over: {
359
+ coins: number;
360
+ hasStamps: boolean;
361
+ totalStamps: number;
362
+ collectedStamps: number;
363
+ stampList: string[];
364
+ room: string;
365
+ gift: boolean;
366
+ doubleCoins: boolean;
367
+ towerCoins: boolean;
368
+ };
369
+ stamp_earned: {
370
+ stamp: number;
371
+ };
294
372
  set_weather: {
295
373
  type: string;
296
374
  intensity: number;
@@ -310,6 +388,64 @@ type ServerMessages = {
310
388
  get_player: {
311
389
  user: RoomUser;
312
390
  };
391
+ buddy_request: {
392
+ id: number;
393
+ };
394
+ buddy_accept: {
395
+ id: number;
396
+ username: string;
397
+ requester: boolean;
398
+ online: boolean;
399
+ };
400
+ buddy_reject: {
401
+ id: number;
402
+ };
403
+ buddy_request_seen: {
404
+ id: number;
405
+ };
406
+ get_buddy: {
407
+ id: number;
408
+ penguin: Record<string, unknown>;
409
+ type: "buddies" | "buddyRequests";
410
+ };
411
+ send_postcard: {
412
+ coins: number;
413
+ };
414
+ stamps_result: {
415
+ stamps: number[];
416
+ inventory: number[];
417
+ coverOnly: number[];
418
+ unseen: number[];
419
+ username: string;
420
+ playerColor: number;
421
+ stampbook: {
422
+ userId: number;
423
+ colour: number;
424
+ clasp: number;
425
+ highlight: number;
426
+ pattern: number;
427
+ };
428
+ coverStamps: {
429
+ stampId: number;
430
+ itemId: number;
431
+ x: number;
432
+ y: number;
433
+ rotation: number;
434
+ }[];
435
+ };
436
+ ignore_add: {
437
+ id: number;
438
+ username: string;
439
+ };
440
+ ignore_remove: {
441
+ id: number;
442
+ };
443
+ get_postcards: {
444
+ postcards: Postcard[];
445
+ };
446
+ get_igloo_open: {
447
+ open: boolean;
448
+ };
313
449
  update_player: {
314
450
  id: number;
315
451
  item: number;
@@ -319,6 +455,13 @@ type ServerMessages = {
319
455
  error: {
320
456
  error: number;
321
457
  };
458
+ kick: {
459
+ reason: string;
460
+ };
461
+ close_with_error: {
462
+ error: string;
463
+ };
464
+ disconnect: void;
322
465
  };
323
466
 
324
467
  type ServerMessageHandler<K extends keyof ServerMessages> = (args: ServerMessages[K]) => void;
@@ -330,6 +473,7 @@ declare class Client extends EventEmitter {
330
473
  player: PlayerData | null;
331
474
  room: number | null;
332
475
  users: Map<number, RoomUser>;
476
+ connected: boolean;
333
477
  private adapter;
334
478
  private loginResult;
335
479
  private log;
@@ -363,15 +507,26 @@ declare class Client extends EventEmitter {
363
507
  equipPhoto(item: number): void;
364
508
  buddyRequest(id: number): void;
365
509
  buddyAccept(id: number): void;
510
+ buddyReject(id: number): void;
511
+ buddyRequestSeen(id: number): void;
512
+ getBuddy(id: number, type: "buddies" | "buddyRequests"): void;
366
513
  removeBuddy(id: number): void;
367
514
  addIgnore(id: number): void;
368
515
  removeIgnore(id: number): void;
369
516
  getPlayer(id: number): void;
370
517
  getAllSlots(): void;
371
518
  getMascots(): void;
519
+ sendPostcard(userId: number, cardId: string): void;
520
+ getStamps(userId: number): void;
521
+ getPostcards(): void;
522
+ getIglooOpen(igloo: number): void;
523
+ joinIgloo(igloo: number, x?: number, y?: number): void;
524
+ gameOver(coins: number): void;
525
+ collectStamp(stamp: number): void;
372
526
  sleep(ms: number): Promise<void>;
373
527
  disconnect(): void;
528
+ private cleanup;
374
529
  private handleMessage;
375
530
  }
376
531
 
377
- export { type AdapterName, BaseAdapter, type Buddy, Client, type ClientMessages, type ClientOptions, type ConnectOptions, type LogFn, type LoginOptions, type LoginResult, type Mascot, type PlayerAppearance, type PlayerData, type PlayerSettings, type QueueUpdate, type RoomUser, type ServerInfo, type ServerMessages, type TokenLoginOptions };
532
+ export { type AdapterName, BaseAdapter, type Buddy, Client, type ClientMessages, type ClientOptions, type ConnectOptions, type LogFn, type LoginOptions, type LoginResult, type Mascot, type PlayerAppearance, type PlayerData, type PlayerSettings, type Postcard, type QueueUpdate, type RoomUser, type ServerInfo, type ServerMessages, type TokenLoginOptions };
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import{EventEmitter as w}from"events";import{io as v}from"socket.io-client";import y from"socket.io-msgpack-parser";var c=class{socket=null;sendMessage(e){this.send("send_message",{message:e})}sendEmote(e){this.send("send_emote",{emote:e})}sendSafe(e){this.send("send_safe",{safe:e})}walk(e,s){this.send("send_position",{x:e,y:s})}sendFrame(e,s){this.send("send_frame",{frame:e,set:s})}snowball(e,s){this.send("snowball",{x:e,y:s})}joinRoom(e,s,n){this.send("join_room",{room:e,x:s??0,y:n??0})}addItem(e){this.send("add_item",{item:e})}equipColor(e){this.send("update_color",{item:e})}equipHead(e){this.send("update_head",{item:e})}equipFace(e){this.send("update_face",{item:e})}equipNeck(e){this.send("update_neck",{item:e})}equipBody(e){this.send("update_body",{item:e})}equipHand(e){this.send("update_hand",{item:e})}equipFeet(e){this.send("update_feet",{item:e})}equipFlag(e){this.send("update_flag",{item:e})}equipPhoto(e){this.send("update_photo",{item:e})}buddyRequest(e){this.send("buddy_request",{id:e})}buddyAccept(e){this.send("buddy_accept",{id:e})}removeBuddy(e){this.send("remove_buddy",{id:e})}addIgnore(e){this.send("add_ignore",{id:e})}removeIgnore(e){this.send("remove_ignore",{id:e})}getPlayer(e){this.send("get_player",{id:e})}getAllSlots(){this.send("get_all_slots",{})}getMascots(){this.send("get_mascots",{})}};var b="wss://play.cpjourney.net",f="skip",m=class extends c{id="CPJourney";async login(e){let s=this.createSocket("/world/login/");return await new Promise((t,o)=>{let a=setTimeout(()=>{s.disconnect(),o(new Error("Login timed out"))},1e4);s.on("connect",()=>{let i=e.secret??f,r="token"in e?{username:e.username,token:e.token,secret:i}:{username:e.username,password:e.password,secret:i};s.emit("message",{action:"login",args:r})}),s.on("message",i=>{if(i.action!=="login")return;clearTimeout(a),s.disconnect();let r=i.args;if(!r.success){o(new Error("Login failed"));return}let u=Object.entries(r.populations).map(([l,p])=>({name:l,population:p}));t({servers:u,key:r.key,username:r.username,moderator:r.moderator,buddyWorlds:r.buddyWorlds??[]})}),s.on("connect_error",i=>{clearTimeout(a),s.disconnect(),o(new Error(`Login connection failed: ${i.message}`))})})}async connect(e,s,n){let t=this.createSocket(`/world/${e.toLowerCase()}/`);return this.socket=t,await new Promise((o,a)=>{let i=!1;t.on("connect",()=>{t.emit("message",{action:"game_auth",args:{username:s.username,key:s.key,createToken:!1,joinInvis:!1,takeoverMascot:!1,token:""}})}),t.on("message",r=>{switch(r.action){case"wait_queue_update":{n?.onQueueUpdate?.(r.args);break}case"game_auth":{if(i)break;if(i=!0,!r.args.success){t.disconnect(),a(new Error("Game auth failed"));return}t.emit("message",{action:"join_server",args:{}}),o();break}}}),t.on("connect_error",r=>{t.disconnect(),a(new Error(`Game connection failed: ${r.message}`))})}),t}send(e,s){if(!this.socket)throw new Error("Not connected");this.socket.emit("message",{action:e,args:s})}disconnect(){this.socket?.disconnect(),this.socket=null}createSocket(e){return v(b,{path:e,parser:y,transports:["polling","websocket"],reconnection:!1})}};var k={CPJourney:m};function h(d){return new k[d]}function _(d){return typeof d=="object"&&d!==null&&"action"in d&&"args"in d}var g=class extends w{player=null;room=null;users=new Map;adapter;loginResult=null;log=null;constructor(e,s){super(),this.adapter=h(e),s?.debug&&(this.log=typeof s.debug=="function"?s.debug:console.log.bind(console))}async login(e){return this.log?.("[login] logging in as",e.username),this.loginResult=await this.adapter.login(e),this.log?.("[login] success \u2014",this.loginResult.servers.length,"servers"),this.loginResult.servers}async connect(e,s){if(!this.loginResult)throw new Error("Must call login() first");this.log?.("[connect] joining",e);let n={...s,onQueueUpdate:o=>{this.log?.("[queue]",`#${o.position}/${o.queueLength}`),this.emit("wait_queue_update",o),s?.onQueueUpdate?.(o)}},t=await this.adapter.connect(e,this.loginResult,n);await new Promise((o,a)=>{let i=setTimeout(()=>{a(new Error("Waiting for load_player timed out"))},1e4),r=!1,u=!1,l=()=>{r&&u&&(clearTimeout(i),o())};t.on("message",p=>{if(_(p))switch(this.handleMessage(p),p.action){case"load_player":r=!0,l();break;case"join_room":u=!0,l();break}}),t.on("disconnect",()=>{clearTimeout(i),(!r||!u)&&a(new Error("Disconnected before fully loaded")),this.emit("disconnect")})})}on(e,s){return super.on(e,s)}off(e,s){return super.off(e,s)}once(e,s){return super.once(e,s)}emit(e,...s){return super.emit(e,...s)}sendMessage(e){this.adapter.sendMessage(e)}sendEmote(e){this.adapter.sendEmote(e)}sendSafe(e){this.adapter.sendSafe(e)}walk(e,s){this.adapter.walk(e,s)}sendFrame(e,s){this.adapter.sendFrame(e,s)}snowball(e,s){this.adapter.snowball(e,s)}joinRoom(e,s,n){this.adapter.joinRoom(e,s,n)}addItem(e){this.adapter.addItem(e)}equipColor(e){this.adapter.equipColor(e)}equipHead(e){this.adapter.equipHead(e)}equipFace(e){this.adapter.equipFace(e)}equipNeck(e){this.adapter.equipNeck(e)}equipBody(e){this.adapter.equipBody(e)}equipHand(e){this.adapter.equipHand(e)}equipFeet(e){this.adapter.equipFeet(e)}equipFlag(e){this.adapter.equipFlag(e)}equipPhoto(e){this.adapter.equipPhoto(e)}buddyRequest(e){this.adapter.buddyRequest(e)}buddyAccept(e){this.adapter.buddyAccept(e)}removeBuddy(e){this.adapter.removeBuddy(e)}addIgnore(e){this.adapter.addIgnore(e)}removeIgnore(e){this.adapter.removeIgnore(e)}getPlayer(e){this.adapter.getPlayer(e)}getAllSlots(){this.adapter.getAllSlots()}getMascots(){this.adapter.getMascots()}sleep(e){return new Promise(s=>setTimeout(s,e))}disconnect(){this.log?.("[disconnect] closing connection"),this.adapter.disconnect(),this.player=null,this.room=null,this.users.clear()}handleMessage(e){let{action:s,args:n}=e;switch(s){case"load_player":{let t=n.user;this.player=t,this.log?.("[load_player]",t.username,`id=${t.id}`);break}case"join_room":{let t=n.room,o=n.users;this.room=t,this.users.clear();for(let a of o)this.users.set(a.id,a);this.log?.("[join_room]",`room=${t}`,`users=${o.length}`);break}case"add_player":{let t=n.user;this.users.set(t.id,t),this.log?.("[add_player]",t.username,`id=${t.id}`);break}case"remove_player":{let t=n.user;this.users.delete(t),this.log?.("[remove_player]",`id=${t}`);break}case"send_position":{let t=n.id,o=this.users.get(t);o&&(o.x=n.x,o.y=n.y);break}case"send_frame":{let t=n.id,o=this.users.get(t);o&&(o.frame=n.frame);break}case"update_player":{let t=n.id,o=n.slot,a=n.item,i=this.users.get(t);i&&o in i&&(i[o]=a);break}default:{this.log?.(`[${s}]`,JSON.stringify(n));break}}this.emit(s,n)}};export{c as BaseAdapter,g as Client};
1
+ import{EventEmitter as A}from"events";import{io as f}from"socket.io-client";import w from"socket.io-msgpack-parser";var p=class{socket=null;sendMessage(e){this.send("send_message",{message:e})}sendEmote(e){this.send("send_emote",{emote:e})}sendSafe(e){this.send("send_safe",{safe:e})}walk(e,s){this.send("send_position",{x:e,y:s})}sendFrame(e,s){this.send("send_frame",{frame:e,set:s})}snowball(e,s){this.send("snowball",{x:e,y:s})}joinRoom(e,s,o){this.send("join_room",{room:e,x:s??0,y:o??0})}addItem(e){this.send("add_item",{item:e})}equipColor(e){this.send("update_color",{item:e})}equipHead(e){this.send("update_head",{item:e})}equipFace(e){this.send("update_face",{item:e})}equipNeck(e){this.send("update_neck",{item:e})}equipBody(e){this.send("update_body",{item:e})}equipHand(e){this.send("update_hand",{item:e})}equipFeet(e){this.send("update_feet",{item:e})}equipFlag(e){this.send("update_flag",{item:e})}equipPhoto(e){this.send("update_photo",{item:e})}buddyRequest(e){this.send("buddy_request",{id:e})}buddyAccept(e){this.send("buddy_accept",{id:e})}buddyReject(e){this.send("buddy_reject",{id:e})}buddyRequestSeen(e){this.send("buddy_request_seen",{id:e})}getBuddy(e,s){this.send("get_buddy",{id:e,type:s})}removeBuddy(e){this.send("remove_buddy",{id:e})}addIgnore(e){this.send("ignore_add",{id:e})}removeIgnore(e){this.send("ignore_remove",{id:e})}getPlayer(e){this.send("get_player",{id:e})}getAllSlots(){this.send("get_all_slots",{})}getMascots(){this.send("get_mascots",{})}sendPostcard(e,s){this.send("send_postcard",{userId:e,cardId:s})}getStamps(e){this.send("get_stamps",{userId:e})}getPostcards(){this.send("get_postcards",{})}getIglooOpen(e){this.send("get_igloo_open",{igloo:e})}joinIgloo(e,s,o){this.send("join_igloo",{igloo:e,x:s??0,y:o??0})}gameOver(e){this.send("game_over",{coins:e})}collectStamp(e){this.send("collect_stamp",{stamp:e})}};var _="wss://play.cpjourney.net",R="skip",l=class extends p{id="CPJourney";async login(e){let s=this.createSocket("/world/login/");return await new Promise((t,n)=>{let a=setTimeout(()=>{s.disconnect(),n(new Error("Login timed out"))},1e4);s.on("connect",()=>{let r=e.secret??R,i="token"in e?{username:e.username,token:e.token,secret:r}:{username:e.username,password:e.password,secret:r};s.emit("message",{action:"login",args:i})}),s.on("message",r=>{if(r.action!=="login")return;clearTimeout(a),s.disconnect();let i=r.args;if(!i.success){n(new Error("Login failed"));return}let u=Object.entries(i.populations).map(([c,m])=>({name:c,population:m}));t({servers:u,key:i.key,username:i.username,moderator:i.moderator,buddyWorlds:i.buddyWorlds??[]})}),s.on("connect_error",r=>{clearTimeout(a),s.disconnect(),n(new Error(`Login connection failed: ${r.message}`))})})}async connect(e,s,o){let t=this.createSocket(`/world/${e.toLowerCase()}/`);return this.socket=t,await new Promise((n,a)=>{let r=!1;t.on("connect",()=>{t.emit("message",{action:"game_auth",args:{username:s.username,key:s.key,createToken:!1,joinInvis:!1,takeoverMascot:!1,token:""}})}),t.on("message",i=>{switch(i.action){case"wait_queue_update":{o?.onQueueUpdate?.(i.args);break}case"game_auth":{if(r)break;if(r=!0,!i.args.success){t.disconnect(),a(new Error("Game auth failed"));return}t.emit("message",{action:"join_server",args:{}}),n();break}}}),t.on("connect_error",i=>{t.disconnect(),a(new Error(`Game connection failed: ${i.message}`))})}),t}send(e,s){if(!this.socket)throw new Error("Not connected");this.socket.emit("message",{action:e,args:s})}disconnect(){this.socket?.disconnect(),this.socket=null}createSocket(e){return f(_,{path:e,parser:w,transports:["polling","websocket"],reconnection:!1})}};import{io as S}from"socket.io-client";import L from"socket.io-msgpack-parser";var P="https://api.cplegacy.com/login",O="https://api.cplegacy.com/token_login";function q(d){let e=d.on.bind(d);return d.on=function(s,o){return s==="message"?e(s,(t,n)=>{o({action:t,args:n??{}})}):e(s,o)},d}var h=class extends p{id="CPLegacy";version="";async login(e){let s="token"in e?O:P,o="token"in e?{username:e.username,token:e.token}:{username:e.username,password:e.password,version:this.version},t=await this.postLogin(s,o);if(!t.success&&t.wantedVersion&&(this.version=t.wantedVersion,o.version=this.version,t=await this.postLogin(s,o)),!t.success)throw new Error(`Login failed: ${t.message??"unknown error"}`);return{servers:Object.entries(t.populations??{}).map(([a,r])=>({name:a,population:r})),key:t.key,username:t.username,moderator:!1,buddyWorlds:[]}}async connect(e,s,o){let t=`wss://${e.toLowerCase()}.server.cplegacy.com`,n=S(t,{path:"/socket.io/",parser:L,transports:["websocket"],reconnection:!1});return this.socket=n,await new Promise((a,r)=>{let i=setTimeout(()=>{n.disconnect(),r(new Error("Game connection timed out"))},15e3);n.on("connect",()=>{n.emit("message","game_auth",{username:s.username,key:s.key,createToken:!1,token:""})}),n.on("message",(u,c)=>{switch(u){case"wait_queue_update":{o?.onQueueUpdate?.(c);break}case"game_auth":{if(!c.success){clearTimeout(i),n.disconnect(),r(new Error("Game auth failed"));return}n.emit("message","load_player",{}),n.emit("message","join_server",{}),clearTimeout(i),a();break}}}),n.on("connect_error",u=>{clearTimeout(i),n.disconnect(),r(new Error(`Game connection failed: ${u.message}`))})}),q(n)}send(e,s){if(!this.socket)throw new Error("Not connected");this.socket.emit("message",e,s)}disconnect(){this.socket?.disconnect(),this.socket=null}async postLogin(e,s){return(await fetch(e,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify(s)})).json()}};var M={CPJourney:l,CPLegacy:h};function v(d){return new M[d]}function y(d){return typeof d=="object"&&d!==null&&"action"in d&&"args"in d}var b=class extends A{player=null;room=null;users=new Map;connected=!1;adapter;loginResult=null;log=null;constructor(e,s){super(),this.adapter=v(e),s?.debug&&(this.log=typeof s.debug=="function"?s.debug:console.log.bind(console))}async login(e){return this.log?.("[login] logging in as",e.username),this.loginResult=await this.adapter.login(e),this.log?.("[login] success \u2014",this.loginResult.servers.length,"servers"),this.loginResult.servers}async connect(e,s){if(!this.loginResult)throw new Error("Must call login() first");this.log?.("[connect] joining",e);let o={...s,onQueueUpdate:n=>{this.log?.("[queue]",`#${n.position}/${n.queueLength}`),this.emit("wait_queue_update",n),s?.onQueueUpdate?.(n)}},t=await this.adapter.connect(e,this.loginResult,o);t.on("message",n=>{y(n)&&this.handleMessage(n)}),t.on("disconnect",()=>{this.log?.("[disconnect] connection lost"),this.cleanup(),this.emit("disconnect")}),await new Promise((n,a)=>{let r=setTimeout(()=>{a(new Error("Waiting for load_player timed out"))},1e4),i=!1,u=!1,c=()=>{i&&u&&(clearTimeout(r),this.connected=!0,n())},m=g=>{if(y(g))switch(g.action){case"load_player":i=!0,c();break;case"join_room":u=!0,c();break;case"kick":clearTimeout(r),t.off("message",m),a(new Error(`Kicked: ${g.args.reason??"unknown"}`));break;case"close_with_error":clearTimeout(r),t.off("message",m),a(new Error(`Kicked: ${g.args.error??"unknown"}`));break}},k=()=>{(!i||!u)&&(clearTimeout(r),a(new Error("Disconnected before fully loaded")))};t.on("message",m),t.once("disconnect",k)})}on(e,s){return super.on(e,s)}off(e,s){return super.off(e,s)}once(e,s){return super.once(e,s)}emit(e,...s){return super.emit(e,...s)}sendMessage(e){this.adapter.sendMessage(e)}sendEmote(e){this.adapter.sendEmote(e)}sendSafe(e){this.adapter.sendSafe(e)}walk(e,s){this.adapter.walk(e,s)}sendFrame(e,s){this.adapter.sendFrame(e,s)}snowball(e,s){this.adapter.snowball(e,s)}joinRoom(e,s,o){this.adapter.joinRoom(e,s,o)}addItem(e){this.adapter.addItem(e)}equipColor(e){this.adapter.equipColor(e)}equipHead(e){this.adapter.equipHead(e)}equipFace(e){this.adapter.equipFace(e)}equipNeck(e){this.adapter.equipNeck(e)}equipBody(e){this.adapter.equipBody(e)}equipHand(e){this.adapter.equipHand(e)}equipFeet(e){this.adapter.equipFeet(e)}equipFlag(e){this.adapter.equipFlag(e)}equipPhoto(e){this.adapter.equipPhoto(e)}buddyRequest(e){this.adapter.buddyRequest(e)}buddyAccept(e){this.adapter.buddyAccept(e)}buddyReject(e){this.adapter.buddyReject(e)}buddyRequestSeen(e){this.adapter.buddyRequestSeen(e)}getBuddy(e,s){this.adapter.getBuddy(e,s)}removeBuddy(e){this.adapter.removeBuddy(e)}addIgnore(e){this.adapter.addIgnore(e)}removeIgnore(e){this.adapter.removeIgnore(e)}getPlayer(e){this.adapter.getPlayer(e)}getAllSlots(){this.adapter.getAllSlots()}getMascots(){this.adapter.getMascots()}sendPostcard(e,s){this.adapter.sendPostcard(e,s)}getStamps(e){this.adapter.getStamps(e)}getPostcards(){this.adapter.getPostcards()}getIglooOpen(e){this.adapter.getIglooOpen(e)}joinIgloo(e,s,o){this.adapter.joinIgloo(e,s,o)}gameOver(e){this.adapter.gameOver(e)}collectStamp(e){this.adapter.collectStamp(e)}sleep(e){return new Promise(s=>setTimeout(s,e))}disconnect(){this.log?.("[disconnect] closing connection"),this.adapter.disconnect(),this.cleanup()}cleanup(){this.connected=!1,this.player=null,this.room=null,this.users.clear()}handleMessage(e){let{action:s,args:o}=e;switch(s){case"load_player":{let t=o.user;this.player=t,this.log?.("[load_player]",t.username,`id=${t.id}`);break}case"join_room":{let t=o.room,n=o.users;this.room=t,this.users.clear();for(let a of n)this.users.set(a.id,a);this.log?.("[join_room]",`room=${t}`,`users=${n.length}`);break}case"add_player":{let t=o.user;this.users.set(t.id,t),this.log?.("[add_player]",t.username,`id=${t.id}`);break}case"remove_player":{let t=o.user;this.users.delete(t),this.log?.("[remove_player]",`id=${t}`);break}case"send_position":{let t=o.id,n=this.users.get(t);n&&(n.x=o.x,n.y=o.y);break}case"send_frame":{let t=o.id,n=this.users.get(t);n&&(n.frame=o.frame);break}case"update_player":{let t=o.id,n=o.slot,a=o.item,r=this.users.get(t);r&&n in r&&(r[n]=a);break}case"kick":{let t=o.reason??"unknown";this.log?.("[kick]",t),this.cleanup();break}case"close_with_error":{let t=o.error??"unknown";this.log?.("[kick]",t),this.cleanup();break}default:{this.log?.(`[${s}]`,JSON.stringify(o));break}}this.emit(s,o)}};export{p as BaseAdapter,b as Client};
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client.ts","../src/adapters/cpjourney-adapter.ts","../src/adapters/base-adapter.ts","../src/adapters/index.ts"],"sourcesContent":["import { EventEmitter } from \"node:events\"\nimport { createAdapter, type AdapterName } from \"./adapters/index.js\"\nimport type { BaseAdapter, ConnectOptions } from \"./adapters/base-adapter.js\"\nimport type { LoginOptions, LoginResult, QueueUpdate, ServerInfo, TokenLoginOptions } from \"./types/adapter-types.js\"\nimport type { ServerMessages } from \"./types/message-types.js\"\nimport type { PlayerData, RoomUser } from \"./types/player-types.js\"\n\ntype ServerMessageHandler<K extends keyof ServerMessages> = (args: ServerMessages[K]) => void\n\nexport type LogFn = (message: string, ...args: unknown[]) => void\n\nexport type ClientOptions = {\n debug?: boolean | LogFn\n}\n\ntype MessagePayload = {\n action: string\n args: Record<string, unknown>\n}\n\nfunction isMessagePayload(msg: unknown): msg is MessagePayload {\n return typeof msg === \"object\" && msg !== null && \"action\" in msg && \"args\" in msg\n}\n\nexport class Client extends EventEmitter {\n player: PlayerData | null = null\n room: number | null = null\n users: Map<number, RoomUser> = new Map()\n\n private adapter: BaseAdapter\n private loginResult: LoginResult | null = null\n private log: LogFn | null = null\n\n constructor(server: AdapterName, options?: ClientOptions) {\n super()\n this.adapter = createAdapter(server)\n\n if (options?.debug) {\n this.log = typeof options.debug === \"function\"\n ? options.debug\n : console.log.bind(console)\n }\n }\n\n async login(options: LoginOptions | TokenLoginOptions): Promise<ServerInfo[]> {\n this.log?.(\"[login] logging in as\", options.username)\n this.loginResult = await this.adapter.login(options)\n this.log?.(\"[login] success —\", this.loginResult.servers.length, \"servers\")\n return this.loginResult.servers\n }\n\n async connect(serverName: string, options?: ConnectOptions): Promise<void> {\n if (!this.loginResult) throw new Error(\"Must call login() first\")\n\n this.log?.(\"[connect] joining\", serverName)\n\n const connectOptions: ConnectOptions = {\n ...options,\n onQueueUpdate: (update: QueueUpdate) => {\n this.log?.(\"[queue]\", `#${update.position}/${update.queueLength}`)\n this.emit(\"wait_queue_update\", update)\n options?.onQueueUpdate?.(update)\n },\n }\n\n const socket = await this.adapter.connect(serverName, this.loginResult, connectOptions)\n\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n reject(new Error(\"Waiting for load_player timed out\"))\n }, 10_000)\n\n let playerLoaded = false\n let roomJoined = false\n\n const checkReady = (): void => {\n if (playerLoaded && roomJoined) {\n clearTimeout(timeout)\n resolve()\n }\n }\n\n socket.on(\"message\", (msg: unknown) => {\n if (!isMessagePayload(msg)) return\n this.handleMessage(msg)\n\n switch (msg.action) {\n case \"load_player\":\n playerLoaded = true\n checkReady()\n break\n case \"join_room\":\n roomJoined = true\n checkReady()\n break\n }\n })\n\n socket.on(\"disconnect\", () => {\n clearTimeout(timeout)\n if (!playerLoaded || !roomJoined) {\n reject(new Error(\"Disconnected before fully loaded\"))\n }\n this.emit(\"disconnect\")\n })\n })\n }\n\n on<K extends keyof ServerMessages>(event: K, listener: ServerMessageHandler<K>): this\n on(event: string, listener: (...args: unknown[]) => void): this\n on(event: string, listener: (...args: unknown[]) => void): this {\n return super.on(event, listener)\n }\n\n off<K extends keyof ServerMessages>(event: K, listener: ServerMessageHandler<K>): this\n off(event: string, listener: (...args: unknown[]) => void): this\n off(event: string, listener: (...args: unknown[]) => void): this {\n return super.off(event, listener)\n }\n\n once<K extends keyof ServerMessages>(event: K, listener: ServerMessageHandler<K>): this\n once(event: string, listener: (...args: unknown[]) => void): this\n once(event: string, listener: (...args: unknown[]) => void): this {\n return super.once(event, listener)\n }\n\n emit<K extends keyof ServerMessages>(event: K, args: ServerMessages[K]): boolean\n emit(event: string, ...args: unknown[]): boolean\n emit(event: string, ...args: unknown[]): boolean {\n return super.emit(event, ...args)\n }\n\n sendMessage(message: string): void { this.adapter.sendMessage(message) }\n sendEmote(emote: number): void { this.adapter.sendEmote(emote) }\n sendSafe(safe: number): void { this.adapter.sendSafe(safe) }\n walk(x: number, y: number): void { this.adapter.walk(x, y) }\n sendFrame(frame: number, set?: boolean): void { this.adapter.sendFrame(frame, set) }\n snowball(x: number, y: number): void { this.adapter.snowball(x, y) }\n joinRoom(room: number, x?: number, y?: number): void { this.adapter.joinRoom(room, x, y) }\n addItem(item: number): void { this.adapter.addItem(item) }\n equipColor(item: number): void { this.adapter.equipColor(item) }\n equipHead(item: number): void { this.adapter.equipHead(item) }\n equipFace(item: number): void { this.adapter.equipFace(item) }\n equipNeck(item: number): void { this.adapter.equipNeck(item) }\n equipBody(item: number): void { this.adapter.equipBody(item) }\n equipHand(item: number): void { this.adapter.equipHand(item) }\n equipFeet(item: number): void { this.adapter.equipFeet(item) }\n equipFlag(item: number): void { this.adapter.equipFlag(item) }\n equipPhoto(item: number): void { this.adapter.equipPhoto(item) }\n buddyRequest(id: number): void { this.adapter.buddyRequest(id) }\n buddyAccept(id: number): void { this.adapter.buddyAccept(id) }\n removeBuddy(id: number): void { this.adapter.removeBuddy(id) }\n addIgnore(id: number): void { this.adapter.addIgnore(id) }\n removeIgnore(id: number): void { this.adapter.removeIgnore(id) }\n getPlayer(id: number): void { this.adapter.getPlayer(id) }\n getAllSlots(): void { this.adapter.getAllSlots() }\n getMascots(): void { this.adapter.getMascots() }\n\n sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms))\n }\n\n disconnect(): void {\n this.log?.(\"[disconnect] closing connection\")\n this.adapter.disconnect()\n this.player = null\n this.room = null\n this.users.clear()\n }\n\n private handleMessage(msg: MessagePayload): void {\n const { action, args } = msg\n\n switch (action) {\n case \"load_player\": {\n const user = args.user as PlayerData\n this.player = user\n this.log?.(\"[load_player]\", user.username, `id=${user.id}`)\n break\n }\n case \"join_room\": {\n const room = args.room as number\n const users = args.users as RoomUser[]\n this.room = room\n this.users.clear()\n for (const user of users) {\n this.users.set(user.id, user)\n }\n this.log?.(\"[join_room]\", `room=${room}`, `users=${users.length}`)\n break\n }\n case \"add_player\": {\n const user = args.user as RoomUser\n this.users.set(user.id, user)\n this.log?.(\"[add_player]\", user.username, `id=${user.id}`)\n break\n }\n case \"remove_player\": {\n const id = args.user as number\n this.users.delete(id)\n this.log?.(\"[remove_player]\", `id=${id}`)\n break\n }\n case \"send_position\": {\n const id = args.id as number\n const user = this.users.get(id)\n if (user) {\n user.x = args.x as number\n user.y = args.y as number\n }\n break\n }\n case \"send_frame\": {\n const id = args.id as number\n const user = this.users.get(id)\n if (user) {\n user.frame = args.frame as number\n }\n break\n }\n case \"update_player\": {\n const id = args.id as number\n const slot = args.slot as string\n const item = args.item as number\n const user = this.users.get(id)\n if (user && slot in user) {\n (user as Record<string, unknown>)[slot] = item\n }\n break\n }\n default: {\n this.log?.(`[${action}]`, JSON.stringify(args))\n break\n }\n }\n\n this.emit(action, args)\n }\n}\n","import { io, type Socket } from \"socket.io-client\"\nimport msgpackParser from \"socket.io-msgpack-parser\"\nimport type { LoginOptions, LoginResult, QueueUpdate, ServerInfo, TokenLoginOptions } from \"../types/adapter-types.js\"\nimport { BaseAdapter, type ConnectOptions } from \"./base-adapter.js\"\n\nconst BASE_URL = \"wss://play.cpjourney.net\"\nconst DEFAULT_SECRET = \"skip\"\n\ntype LoginResponse = {\n success: boolean\n username: string\n key: string\n populations: Record<string, number>\n moderator: boolean\n buddyWorlds: string[]\n}\n\ntype GameAuthResponse = {\n success: boolean\n token?: string\n}\n\ntype ServerMessage = {\n action: string\n args: Record<string, unknown>\n}\n\nexport class CpjourneyAdapter extends BaseAdapter {\n readonly id = \"CPJourney\"\n\n async login(options: LoginOptions | TokenLoginOptions): Promise<LoginResult> {\n const loginSocket = this.createSocket(\"/world/login/\")\n\n const result = await new Promise<LoginResult>((resolve, reject) => {\n const timeout = setTimeout(() => {\n loginSocket.disconnect()\n reject(new Error(\"Login timed out\"))\n }, 10_000)\n\n loginSocket.on(\"connect\", () => {\n const secret = options.secret ?? DEFAULT_SECRET\n const args = \"token\" in options\n ? { username: options.username, token: options.token, secret }\n : { username: options.username, password: options.password, secret }\n\n loginSocket.emit(\"message\", { action: \"login\", args })\n })\n\n loginSocket.on(\"message\", (msg: ServerMessage) => {\n if (msg.action !== \"login\") return\n\n clearTimeout(timeout)\n loginSocket.disconnect()\n\n const response = msg.args as LoginResponse\n\n if (!response.success) {\n reject(new Error(\"Login failed\"))\n return\n }\n\n const servers: ServerInfo[] = Object.entries(response.populations).map(\n ([name, population]) => ({ name, population })\n )\n\n resolve({\n servers,\n key: response.key,\n username: response.username,\n moderator: response.moderator,\n buddyWorlds: response.buddyWorlds ?? [],\n })\n })\n\n loginSocket.on(\"connect_error\", (err: Error) => {\n clearTimeout(timeout)\n loginSocket.disconnect()\n reject(new Error(`Login connection failed: ${err.message}`))\n })\n })\n\n return result\n }\n\n async connect(serverName: string, loginResult: LoginResult, options?: ConnectOptions): Promise<Socket> {\n const gameSocket = this.createSocket(`/world/${serverName.toLowerCase()}/`)\n this.socket = gameSocket\n\n await new Promise<void>((resolve, reject) => {\n let authSent = false\n\n gameSocket.on(\"connect\", () => {\n gameSocket.emit(\"message\", {\n action: \"game_auth\",\n args: {\n username: loginResult.username,\n key: loginResult.key,\n createToken: false,\n joinInvis: false,\n takeoverMascot: false,\n token: \"\",\n },\n })\n })\n\n gameSocket.on(\"message\", (msg: ServerMessage) => {\n switch (msg.action) {\n case \"wait_queue_update\": {\n options?.onQueueUpdate?.(msg.args as QueueUpdate)\n break\n }\n case \"game_auth\": {\n if (authSent) break\n authSent = true\n\n const response = msg.args as GameAuthResponse\n if (!response.success) {\n gameSocket.disconnect()\n reject(new Error(\"Game auth failed\"))\n return\n }\n\n gameSocket.emit(\"message\", { action: \"join_server\", args: {} })\n resolve()\n break\n }\n }\n })\n\n gameSocket.on(\"connect_error\", (err: Error) => {\n gameSocket.disconnect()\n reject(new Error(`Game connection failed: ${err.message}`))\n })\n })\n\n return gameSocket\n }\n\n send(action: string, args: Record<string, unknown>): void {\n if (!this.socket) throw new Error(\"Not connected\")\n this.socket.emit(\"message\", { action, args })\n }\n\n disconnect(): void {\n this.socket?.disconnect()\n this.socket = null\n }\n\n private createSocket(path: string): Socket {\n return io(BASE_URL, {\n path,\n parser: msgpackParser,\n transports: [\"polling\", \"websocket\"],\n reconnection: false,\n })\n }\n}\n","import type { Socket } from \"socket.io-client\"\nimport type { LoginOptions, LoginResult, QueueUpdate, TokenLoginOptions } from \"../types/adapter-types.js\"\n\nexport type ConnectOptions = {\n onQueueUpdate?: (update: QueueUpdate) => void\n}\n\nexport abstract class BaseAdapter {\n abstract readonly id: string\n protected socket: Socket | null = null\n\n abstract login(options: LoginOptions | TokenLoginOptions): Promise<LoginResult>\n abstract connect(serverName: string, loginResult: LoginResult, options?: ConnectOptions): Promise<Socket>\n abstract disconnect(): void\n abstract send(action: string, args: Record<string, unknown>): void\n\n sendMessage(message: string): void {\n this.send(\"send_message\", { message })\n }\n\n sendEmote(emote: number): void {\n this.send(\"send_emote\", { emote })\n }\n\n sendSafe(safe: number): void {\n this.send(\"send_safe\", { safe })\n }\n\n walk(x: number, y: number): void {\n this.send(\"send_position\", { x, y })\n }\n\n sendFrame(frame: number, set?: boolean): void {\n this.send(\"send_frame\", { frame, set })\n }\n\n snowball(x: number, y: number): void {\n this.send(\"snowball\", { x, y })\n }\n\n joinRoom(room: number, x?: number, y?: number): void {\n this.send(\"join_room\", { room, x: x ?? 0, y: y ?? 0 })\n }\n\n addItem(item: number): void {\n this.send(\"add_item\", { item })\n }\n\n equipColor(item: number): void {\n this.send(\"update_color\", { item })\n }\n\n equipHead(item: number): void {\n this.send(\"update_head\", { item })\n }\n\n equipFace(item: number): void {\n this.send(\"update_face\", { item })\n }\n\n equipNeck(item: number): void {\n this.send(\"update_neck\", { item })\n }\n\n equipBody(item: number): void {\n this.send(\"update_body\", { item })\n }\n\n equipHand(item: number): void {\n this.send(\"update_hand\", { item })\n }\n\n equipFeet(item: number): void {\n this.send(\"update_feet\", { item })\n }\n\n equipFlag(item: number): void {\n this.send(\"update_flag\", { item })\n }\n\n equipPhoto(item: number): void {\n this.send(\"update_photo\", { item })\n }\n\n buddyRequest(id: number): void {\n this.send(\"buddy_request\", { id })\n }\n\n buddyAccept(id: number): void {\n this.send(\"buddy_accept\", { id })\n }\n\n removeBuddy(id: number): void {\n this.send(\"remove_buddy\", { id })\n }\n\n addIgnore(id: number): void {\n this.send(\"add_ignore\", { id })\n }\n\n removeIgnore(id: number): void {\n this.send(\"remove_ignore\", { id })\n }\n\n getPlayer(id: number): void {\n this.send(\"get_player\", { id })\n }\n\n getAllSlots(): void {\n this.send(\"get_all_slots\", {})\n }\n\n getMascots(): void {\n this.send(\"get_mascots\", {})\n }\n}\n","import type { BaseAdapter } from \"./base-adapter.js\"\nimport { CpjourneyAdapter } from \"./cpjourney-adapter.js\"\n\nconst ADAPTERS = {\n CPJourney: CpjourneyAdapter,\n} as const\n\nexport type AdapterName = keyof typeof ADAPTERS\n\nexport function createAdapter(name: AdapterName): BaseAdapter {\n return new ADAPTERS[name]()\n}\n"],"mappings":"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","names":["EventEmitter","io","msgpackParser","BaseAdapter","message","emote","safe","x","y","frame","set","room","item","id","BASE_URL","DEFAULT_SECRET","CpjourneyAdapter","BaseAdapter","options","loginSocket","resolve","reject","timeout","secret","args","msg","response","servers","name","population","err","serverName","loginResult","gameSocket","authSent","action","path","io","msgpackParser","ADAPTERS","CpjourneyAdapter","createAdapter","name","isMessagePayload","msg","Client","EventEmitter","server","options","createAdapter","serverName","connectOptions","update","socket","resolve","reject","timeout","playerLoaded","roomJoined","checkReady","event","listener","args","message","emote","safe","x","y","frame","set","room","item","id","ms","action","user","users","slot"]}
1
+ {"version":3,"sources":["../src/client.ts","../src/adapters/cpjourney-adapter.ts","../src/adapters/base-adapter.ts","../src/adapters/cplegacy-adapter.ts","../src/adapters/index.ts"],"sourcesContent":["import { EventEmitter } from \"node:events\"\nimport { createAdapter, type AdapterName } from \"./adapters/index.js\"\nimport type { BaseAdapter, ConnectOptions } from \"./adapters/base-adapter.js\"\nimport type { LoginOptions, LoginResult, QueueUpdate, ServerInfo, TokenLoginOptions } from \"./types/adapter-types.js\"\nimport type { ServerMessages } from \"./types/message-types.js\"\nimport type { PlayerData, RoomUser } from \"./types/player-types.js\"\n\ntype ServerMessageHandler<K extends keyof ServerMessages> = (args: ServerMessages[K]) => void\n\nexport type LogFn = (message: string, ...args: unknown[]) => void\n\nexport type ClientOptions = {\n debug?: boolean | LogFn\n}\n\ntype MessagePayload = {\n action: string\n args: Record<string, unknown>\n}\n\nfunction isMessagePayload(msg: unknown): msg is MessagePayload {\n return typeof msg === \"object\" && msg !== null && \"action\" in msg && \"args\" in msg\n}\n\nexport class Client extends EventEmitter {\n player: PlayerData | null = null\n room: number | null = null\n users: Map<number, RoomUser> = new Map()\n connected = false\n\n private adapter: BaseAdapter\n private loginResult: LoginResult | null = null\n private log: LogFn | null = null\n\n constructor(server: AdapterName, options?: ClientOptions) {\n super()\n this.adapter = createAdapter(server)\n\n if (options?.debug) {\n this.log = typeof options.debug === \"function\"\n ? options.debug\n : console.log.bind(console)\n }\n }\n\n async login(options: LoginOptions | TokenLoginOptions): Promise<ServerInfo[]> {\n this.log?.(\"[login] logging in as\", options.username)\n this.loginResult = await this.adapter.login(options)\n this.log?.(\"[login] success —\", this.loginResult.servers.length, \"servers\")\n return this.loginResult.servers\n }\n\n async connect(serverName: string, options?: ConnectOptions): Promise<void> {\n if (!this.loginResult) throw new Error(\"Must call login() first\")\n\n this.log?.(\"[connect] joining\", serverName)\n\n const connectOptions: ConnectOptions = {\n ...options,\n onQueueUpdate: (update: QueueUpdate) => {\n this.log?.(\"[queue]\", `#${update.position}/${update.queueLength}`)\n this.emit(\"wait_queue_update\", update)\n options?.onQueueUpdate?.(update)\n },\n }\n\n const socket = await this.adapter.connect(serverName, this.loginResult, connectOptions)\n\n socket.on(\"message\", (msg: unknown) => {\n if (!isMessagePayload(msg)) return\n this.handleMessage(msg)\n })\n\n socket.on(\"disconnect\", () => {\n this.log?.(\"[disconnect] connection lost\")\n this.cleanup()\n this.emit(\"disconnect\")\n })\n\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n reject(new Error(\"Waiting for load_player timed out\"))\n }, 10_000)\n\n let playerLoaded = false\n let roomJoined = false\n\n const checkReady = (): void => {\n if (playerLoaded && roomJoined) {\n clearTimeout(timeout)\n this.connected = true\n resolve()\n }\n }\n\n const onMessage = (msg: unknown): void => {\n if (!isMessagePayload(msg)) return\n switch (msg.action) {\n case \"load_player\":\n playerLoaded = true\n checkReady()\n break\n case \"join_room\":\n roomJoined = true\n checkReady()\n break\n case \"kick\":\n clearTimeout(timeout)\n socket.off(\"message\", onMessage)\n reject(new Error(`Kicked: ${(msg.args as { reason?: string }).reason ?? \"unknown\"}`))\n break\n case \"close_with_error\":\n clearTimeout(timeout)\n socket.off(\"message\", onMessage)\n reject(new Error(`Kicked: ${(msg.args as { error?: string }).error ?? \"unknown\"}`))\n break\n }\n }\n\n const onDisconnect = (): void => {\n if (!playerLoaded || !roomJoined) {\n clearTimeout(timeout)\n reject(new Error(\"Disconnected before fully loaded\"))\n }\n }\n\n socket.on(\"message\", onMessage)\n socket.once(\"disconnect\", onDisconnect)\n })\n }\n\n on<K extends keyof ServerMessages>(event: K, listener: ServerMessageHandler<K>): this\n on(event: string, listener: (...args: unknown[]) => void): this\n on(event: string, listener: (...args: unknown[]) => void): this {\n return super.on(event, listener)\n }\n\n off<K extends keyof ServerMessages>(event: K, listener: ServerMessageHandler<K>): this\n off(event: string, listener: (...args: unknown[]) => void): this\n off(event: string, listener: (...args: unknown[]) => void): this {\n return super.off(event, listener)\n }\n\n once<K extends keyof ServerMessages>(event: K, listener: ServerMessageHandler<K>): this\n once(event: string, listener: (...args: unknown[]) => void): this\n once(event: string, listener: (...args: unknown[]) => void): this {\n return super.once(event, listener)\n }\n\n emit<K extends keyof ServerMessages>(event: K, args: ServerMessages[K]): boolean\n emit(event: string, ...args: unknown[]): boolean\n emit(event: string, ...args: unknown[]): boolean {\n return super.emit(event, ...args)\n }\n\n sendMessage(message: string): void { this.adapter.sendMessage(message) }\n sendEmote(emote: number): void { this.adapter.sendEmote(emote) }\n sendSafe(safe: number): void { this.adapter.sendSafe(safe) }\n walk(x: number, y: number): void { this.adapter.walk(x, y) }\n sendFrame(frame: number, set?: boolean): void { this.adapter.sendFrame(frame, set) }\n snowball(x: number, y: number): void { this.adapter.snowball(x, y) }\n joinRoom(room: number, x?: number, y?: number): void { this.adapter.joinRoom(room, x, y) }\n addItem(item: number): void { this.adapter.addItem(item) }\n equipColor(item: number): void { this.adapter.equipColor(item) }\n equipHead(item: number): void { this.adapter.equipHead(item) }\n equipFace(item: number): void { this.adapter.equipFace(item) }\n equipNeck(item: number): void { this.adapter.equipNeck(item) }\n equipBody(item: number): void { this.adapter.equipBody(item) }\n equipHand(item: number): void { this.adapter.equipHand(item) }\n equipFeet(item: number): void { this.adapter.equipFeet(item) }\n equipFlag(item: number): void { this.adapter.equipFlag(item) }\n equipPhoto(item: number): void { this.adapter.equipPhoto(item) }\n buddyRequest(id: number): void { this.adapter.buddyRequest(id) }\n buddyAccept(id: number): void { this.adapter.buddyAccept(id) }\n buddyReject(id: number): void { this.adapter.buddyReject(id) }\n buddyRequestSeen(id: number): void { this.adapter.buddyRequestSeen(id) }\n getBuddy(id: number, type: \"buddies\" | \"buddyRequests\"): void { this.adapter.getBuddy(id, type) }\n removeBuddy(id: number): void { this.adapter.removeBuddy(id) }\n addIgnore(id: number): void { this.adapter.addIgnore(id) }\n removeIgnore(id: number): void { this.adapter.removeIgnore(id) }\n getPlayer(id: number): void { this.adapter.getPlayer(id) }\n getAllSlots(): void { this.adapter.getAllSlots() }\n getMascots(): void { this.adapter.getMascots() }\n sendPostcard(userId: number, cardId: string): void { this.adapter.sendPostcard(userId, cardId) }\n getStamps(userId: number): void { this.adapter.getStamps(userId) }\n getPostcards(): void { this.adapter.getPostcards() }\n getIglooOpen(igloo: number): void { this.adapter.getIglooOpen(igloo) }\n joinIgloo(igloo: number, x?: number, y?: number): void { this.adapter.joinIgloo(igloo, x, y) }\n gameOver(coins: number): void { this.adapter.gameOver(coins) }\n collectStamp(stamp: number): void { this.adapter.collectStamp(stamp) }\n\n sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms))\n }\n\n disconnect(): void {\n this.log?.(\"[disconnect] closing connection\")\n this.adapter.disconnect()\n this.cleanup()\n }\n\n private cleanup(): void {\n this.connected = false\n this.player = null\n this.room = null\n this.users.clear()\n }\n\n private handleMessage(msg: MessagePayload): void {\n const { action, args } = msg\n\n switch (action) {\n case \"load_player\": {\n const user = args.user as PlayerData\n this.player = user\n this.log?.(\"[load_player]\", user.username, `id=${user.id}`)\n break\n }\n case \"join_room\": {\n const room = args.room as number\n const users = args.users as RoomUser[]\n this.room = room\n this.users.clear()\n for (const user of users) {\n this.users.set(user.id, user)\n }\n this.log?.(\"[join_room]\", `room=${room}`, `users=${users.length}`)\n break\n }\n case \"add_player\": {\n const user = args.user as RoomUser\n this.users.set(user.id, user)\n this.log?.(\"[add_player]\", user.username, `id=${user.id}`)\n break\n }\n case \"remove_player\": {\n const id = args.user as number\n this.users.delete(id)\n this.log?.(\"[remove_player]\", `id=${id}`)\n break\n }\n case \"send_position\": {\n const id = args.id as number\n const user = this.users.get(id)\n if (user) {\n user.x = args.x as number\n user.y = args.y as number\n }\n break\n }\n case \"send_frame\": {\n const id = args.id as number\n const user = this.users.get(id)\n if (user) {\n user.frame = args.frame as number\n }\n break\n }\n case \"update_player\": {\n const id = args.id as number\n const slot = args.slot as string\n const item = args.item as number\n const user = this.users.get(id)\n if (user && slot in user) {\n (user as Record<string, unknown>)[slot] = item\n }\n break\n }\n case \"kick\": {\n const reason = (args as { reason?: string }).reason ?? \"unknown\"\n this.log?.(\"[kick]\", reason)\n this.cleanup()\n break\n }\n case \"close_with_error\": {\n const error = (args as { error?: string }).error ?? \"unknown\"\n this.log?.(\"[kick]\", error)\n this.cleanup()\n break\n }\n default: {\n this.log?.(`[${action}]`, JSON.stringify(args))\n break\n }\n }\n\n this.emit(action, args)\n }\n}\n","import { io, type Socket } from \"socket.io-client\"\nimport msgpackParser from \"socket.io-msgpack-parser\"\nimport type { LoginOptions, LoginResult, QueueUpdate, ServerInfo, TokenLoginOptions } from \"../types/adapter-types.js\"\nimport { BaseAdapter, type ConnectOptions } from \"./base-adapter.js\"\n\nconst BASE_URL = \"wss://play.cpjourney.net\"\nconst DEFAULT_SECRET = \"skip\"\n\ntype LoginResponse = {\n success: boolean\n username: string\n key: string\n populations: Record<string, number>\n moderator: boolean\n buddyWorlds: string[]\n}\n\ntype GameAuthResponse = {\n success: boolean\n token?: string\n}\n\ntype ServerMessage = {\n action: string\n args: Record<string, unknown>\n}\n\nexport class CpjourneyAdapter extends BaseAdapter {\n readonly id = \"CPJourney\"\n\n async login(options: LoginOptions | TokenLoginOptions): Promise<LoginResult> {\n const loginSocket = this.createSocket(\"/world/login/\")\n\n const result = await new Promise<LoginResult>((resolve, reject) => {\n const timeout = setTimeout(() => {\n loginSocket.disconnect()\n reject(new Error(\"Login timed out\"))\n }, 10_000)\n\n loginSocket.on(\"connect\", () => {\n const secret = options.secret ?? DEFAULT_SECRET\n const args = \"token\" in options\n ? { username: options.username, token: options.token, secret }\n : { username: options.username, password: options.password, secret }\n\n loginSocket.emit(\"message\", { action: \"login\", args })\n })\n\n loginSocket.on(\"message\", (msg: ServerMessage) => {\n if (msg.action !== \"login\") return\n\n clearTimeout(timeout)\n loginSocket.disconnect()\n\n const response = msg.args as LoginResponse\n\n if (!response.success) {\n reject(new Error(\"Login failed\"))\n return\n }\n\n const servers: ServerInfo[] = Object.entries(response.populations).map(\n ([name, population]) => ({ name, population })\n )\n\n resolve({\n servers,\n key: response.key,\n username: response.username,\n moderator: response.moderator,\n buddyWorlds: response.buddyWorlds ?? [],\n })\n })\n\n loginSocket.on(\"connect_error\", (err: Error) => {\n clearTimeout(timeout)\n loginSocket.disconnect()\n reject(new Error(`Login connection failed: ${err.message}`))\n })\n })\n\n return result\n }\n\n async connect(serverName: string, loginResult: LoginResult, options?: ConnectOptions): Promise<Socket> {\n const gameSocket = this.createSocket(`/world/${serverName.toLowerCase()}/`)\n this.socket = gameSocket\n\n await new Promise<void>((resolve, reject) => {\n let authSent = false\n\n gameSocket.on(\"connect\", () => {\n gameSocket.emit(\"message\", {\n action: \"game_auth\",\n args: {\n username: loginResult.username,\n key: loginResult.key,\n createToken: false,\n joinInvis: false,\n takeoverMascot: false,\n token: \"\",\n },\n })\n })\n\n gameSocket.on(\"message\", (msg: ServerMessage) => {\n switch (msg.action) {\n case \"wait_queue_update\": {\n options?.onQueueUpdate?.(msg.args as QueueUpdate)\n break\n }\n case \"game_auth\": {\n if (authSent) break\n authSent = true\n\n const response = msg.args as GameAuthResponse\n if (!response.success) {\n gameSocket.disconnect()\n reject(new Error(\"Game auth failed\"))\n return\n }\n\n gameSocket.emit(\"message\", { action: \"join_server\", args: {} })\n resolve()\n break\n }\n }\n })\n\n gameSocket.on(\"connect_error\", (err: Error) => {\n gameSocket.disconnect()\n reject(new Error(`Game connection failed: ${err.message}`))\n })\n })\n\n return gameSocket\n }\n\n send(action: string, args: Record<string, unknown>): void {\n if (!this.socket) throw new Error(\"Not connected\")\n this.socket.emit(\"message\", { action, args })\n }\n\n disconnect(): void {\n this.socket?.disconnect()\n this.socket = null\n }\n\n private createSocket(path: string): Socket {\n return io(BASE_URL, {\n path,\n parser: msgpackParser,\n transports: [\"polling\", \"websocket\"],\n reconnection: false,\n })\n }\n}\n","import type { Socket } from \"socket.io-client\"\nimport type { LoginOptions, LoginResult, QueueUpdate, TokenLoginOptions } from \"../types/adapter-types.js\"\n\nexport type ConnectOptions = {\n onQueueUpdate?: (update: QueueUpdate) => void\n}\n\nexport abstract class BaseAdapter {\n abstract readonly id: string\n protected socket: Socket | null = null\n\n abstract login(options: LoginOptions | TokenLoginOptions): Promise<LoginResult>\n abstract connect(serverName: string, loginResult: LoginResult, options?: ConnectOptions): Promise<Socket>\n abstract disconnect(): void\n abstract send(action: string, args: Record<string, unknown>): void\n\n sendMessage(message: string): void {\n this.send(\"send_message\", { message })\n }\n\n sendEmote(emote: number): void {\n this.send(\"send_emote\", { emote })\n }\n\n sendSafe(safe: number): void {\n this.send(\"send_safe\", { safe })\n }\n\n walk(x: number, y: number): void {\n this.send(\"send_position\", { x, y })\n }\n\n sendFrame(frame: number, set?: boolean): void {\n this.send(\"send_frame\", { frame, set })\n }\n\n snowball(x: number, y: number): void {\n this.send(\"snowball\", { x, y })\n }\n\n joinRoom(room: number, x?: number, y?: number): void {\n this.send(\"join_room\", { room, x: x ?? 0, y: y ?? 0 })\n }\n\n addItem(item: number): void {\n this.send(\"add_item\", { item })\n }\n\n equipColor(item: number): void {\n this.send(\"update_color\", { item })\n }\n\n equipHead(item: number): void {\n this.send(\"update_head\", { item })\n }\n\n equipFace(item: number): void {\n this.send(\"update_face\", { item })\n }\n\n equipNeck(item: number): void {\n this.send(\"update_neck\", { item })\n }\n\n equipBody(item: number): void {\n this.send(\"update_body\", { item })\n }\n\n equipHand(item: number): void {\n this.send(\"update_hand\", { item })\n }\n\n equipFeet(item: number): void {\n this.send(\"update_feet\", { item })\n }\n\n equipFlag(item: number): void {\n this.send(\"update_flag\", { item })\n }\n\n equipPhoto(item: number): void {\n this.send(\"update_photo\", { item })\n }\n\n buddyRequest(id: number): void {\n this.send(\"buddy_request\", { id })\n }\n\n buddyAccept(id: number): void {\n this.send(\"buddy_accept\", { id })\n }\n\n buddyReject(id: number): void {\n this.send(\"buddy_reject\", { id })\n }\n\n buddyRequestSeen(id: number): void {\n this.send(\"buddy_request_seen\", { id })\n }\n\n getBuddy(id: number, type: \"buddies\" | \"buddyRequests\"): void {\n this.send(\"get_buddy\", { id, type })\n }\n\n removeBuddy(id: number): void {\n this.send(\"remove_buddy\", { id })\n }\n\n addIgnore(id: number): void {\n this.send(\"ignore_add\", { id })\n }\n\n removeIgnore(id: number): void {\n this.send(\"ignore_remove\", { id })\n }\n\n getPlayer(id: number): void {\n this.send(\"get_player\", { id })\n }\n\n getAllSlots(): void {\n this.send(\"get_all_slots\", {})\n }\n\n getMascots(): void {\n this.send(\"get_mascots\", {})\n }\n\n sendPostcard(userId: number, cardId: string): void {\n this.send(\"send_postcard\", { userId, cardId })\n }\n\n getStamps(userId: number): void {\n this.send(\"get_stamps\", { userId })\n }\n\n getPostcards(): void {\n this.send(\"get_postcards\", {})\n }\n\n getIglooOpen(igloo: number): void {\n this.send(\"get_igloo_open\", { igloo })\n }\n\n joinIgloo(igloo: number, x?: number, y?: number): void {\n this.send(\"join_igloo\", { igloo, x: x ?? 0, y: y ?? 0 })\n }\n\n gameOver(coins: number): void {\n this.send(\"game_over\", { coins })\n }\n\n collectStamp(stamp: number): void {\n this.send(\"collect_stamp\", { stamp })\n }\n}\n","import { io, type Socket } from \"socket.io-client\"\nimport msgpackParser from \"socket.io-msgpack-parser\"\nimport type { LoginOptions, LoginResult, QueueUpdate, ServerInfo, TokenLoginOptions } from \"../types/adapter-types.js\"\nimport { BaseAdapter, type ConnectOptions } from \"./base-adapter.js\"\n\nconst LOGIN_URL = \"https://api.cplegacy.com/login\"\nconst TOKEN_LOGIN_URL = \"https://api.cplegacy.com/token_login\"\n\ntype LoginResponse = {\n success: boolean\n username: string\n key: string\n populations: Record<string, number>\n requires2FA: boolean\n message?: string\n wantedVersion?: string\n}\n\ntype GameAuthResponse = {\n success: boolean\n}\n\n/**\n * Wraps a CPLegacy socket to normalize its positional message format\n * `(\"message\", action, args)` into the `{ action, args }` envelope\n * that the Client class expects.\n */\nfunction wrapSocket(raw: Socket): Socket {\n const original = raw.on.bind(raw)\n\n raw.on = function (event: string, listener: (...args: unknown[]) => void) {\n if (event === \"message\") {\n return original(event, (action: unknown, args: unknown) => {\n listener({ action, args: args ?? {} })\n })\n }\n return original(event, listener)\n } as typeof raw.on\n\n return raw\n}\n\nexport class CplegacyAdapter extends BaseAdapter {\n readonly id = \"CPLegacy\"\n private version = \"\"\n\n async login(options: LoginOptions | TokenLoginOptions): Promise<LoginResult> {\n const url = \"token\" in options ? TOKEN_LOGIN_URL : LOGIN_URL\n const body: Record<string, unknown> = \"token\" in options\n ? { username: options.username, token: options.token }\n : { username: options.username, password: options.password, version: this.version }\n\n let data = await this.postLogin(url, body)\n\n // Version negotiation: server returns wantedVersion when ours is stale/empty\n if (!data.success && data.wantedVersion) {\n this.version = data.wantedVersion\n body.version = this.version\n data = await this.postLogin(url, body)\n }\n\n if (!data.success) {\n throw new Error(`Login failed: ${data.message ?? \"unknown error\"}`)\n }\n\n const servers: ServerInfo[] = Object.entries(data.populations ?? {}).map(\n ([name, population]) => ({ name, population })\n )\n\n return {\n servers,\n key: data.key,\n username: data.username,\n moderator: false,\n buddyWorlds: [],\n }\n }\n\n async connect(serverName: string, loginResult: LoginResult, options?: ConnectOptions): Promise<Socket> {\n const wsUrl = `wss://${serverName.toLowerCase()}.server.cplegacy.com`\n const rawSocket = io(wsUrl, {\n path: \"/socket.io/\",\n parser: msgpackParser,\n transports: [\"websocket\"],\n reconnection: false,\n })\n this.socket = rawSocket\n\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n rawSocket.disconnect()\n reject(new Error(\"Game connection timed out\"))\n }, 15_000)\n\n rawSocket.on(\"connect\", () => {\n rawSocket.emit(\"message\", \"game_auth\", {\n username: loginResult.username,\n key: loginResult.key,\n createToken: false,\n token: \"\",\n })\n })\n\n rawSocket.on(\"message\", (action: string, args: Record<string, unknown>) => {\n switch (action) {\n case \"wait_queue_update\": {\n options?.onQueueUpdate?.(args as unknown as QueueUpdate)\n break\n }\n case \"game_auth\": {\n const response = args as unknown as GameAuthResponse\n if (!response.success) {\n clearTimeout(timeout)\n rawSocket.disconnect()\n reject(new Error(\"Game auth failed\"))\n return\n }\n\n // CPLegacy requires explicitly requesting load_player before join_server\n rawSocket.emit(\"message\", \"load_player\", {})\n rawSocket.emit(\"message\", \"join_server\", {})\n clearTimeout(timeout)\n resolve()\n break\n }\n }\n })\n\n rawSocket.on(\"connect_error\", (err: Error) => {\n clearTimeout(timeout)\n rawSocket.disconnect()\n reject(new Error(`Game connection failed: ${err.message}`))\n })\n })\n\n // Return wrapped socket so Client receives normalized { action, args } messages\n return wrapSocket(rawSocket)\n }\n\n send(action: string, args: Record<string, unknown>): void {\n if (!this.socket) throw new Error(\"Not connected\")\n this.socket.emit(\"message\", action, args)\n }\n\n disconnect(): void {\n this.socket?.disconnect()\n this.socket = null\n }\n\n private async postLogin(url: string, body: Record<string, unknown>): Promise<LoginResponse> {\n const resp = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n },\n body: JSON.stringify(body),\n })\n\n return resp.json() as Promise<LoginResponse>\n }\n}\n","import type { BaseAdapter } from \"./base-adapter.js\"\nimport { CpjourneyAdapter } from \"./cpjourney-adapter.js\"\nimport { CplegacyAdapter } from \"./cplegacy-adapter.js\"\n\nconst ADAPTERS = {\n CPJourney: CpjourneyAdapter,\n CPLegacy: CplegacyAdapter,\n} as const\n\nexport type AdapterName = keyof typeof ADAPTERS\n\nexport function createAdapter(name: AdapterName): BaseAdapter {\n return new ADAPTERS[name]()\n}\n"],"mappings":"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","names":["EventEmitter","io","msgpackParser","BaseAdapter","message","emote","safe","x","y","frame","set","room","item","id","type","userId","cardId","igloo","coins","stamp","BASE_URL","DEFAULT_SECRET","CpjourneyAdapter","BaseAdapter","options","loginSocket","resolve","reject","timeout","secret","args","msg","response","servers","name","population","err","serverName","loginResult","gameSocket","authSent","action","path","io","msgpackParser","io","msgpackParser","LOGIN_URL","TOKEN_LOGIN_URL","wrapSocket","raw","original","event","listener","action","args","CplegacyAdapter","BaseAdapter","options","url","body","data","name","population","serverName","loginResult","wsUrl","rawSocket","io","msgpackParser","resolve","reject","timeout","err","ADAPTERS","CpjourneyAdapter","CplegacyAdapter","createAdapter","name","isMessagePayload","msg","Client","EventEmitter","server","options","createAdapter","serverName","connectOptions","update","socket","resolve","reject","timeout","playerLoaded","roomJoined","checkReady","onMessage","onDisconnect","event","listener","args","message","emote","safe","x","y","frame","set","room","item","id","type","userId","cardId","igloo","coins","stamp","ms","action","user","users","slot","reason","error"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shaunlwm/pickle.ts",
3
- "version": "0.0.2",
3
+ "version": "0.2.0",
4
4
  "description": "Club Penguin Private Server client library",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",