connectbase-client 0.6.11 → 0.6.13
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 +4 -2
- package/dist/cli.js +24 -11
- package/dist/connect-base.umd.js +2 -2
- package/dist/index.d.mts +179 -1
- package/dist/index.d.ts +179 -1
- package/dist/index.js +397 -0
- package/dist/index.mjs +397 -0
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -4356,6 +4356,403 @@ var GameAPI = class {
|
|
|
4356
4356
|
throw new Error(`Failed to delete room: ${response.statusText}`);
|
|
4357
4357
|
}
|
|
4358
4358
|
}
|
|
4359
|
+
// ==================== Matchmaking ====================
|
|
4360
|
+
/**
|
|
4361
|
+
* 매치메이킹 큐에 참가
|
|
4362
|
+
*/
|
|
4363
|
+
async joinQueue(req) {
|
|
4364
|
+
const id = this.appId || "";
|
|
4365
|
+
const response = await fetch(`${this.gameServerUrl}/v1/game/${id}/matchmaking/queue`, {
|
|
4366
|
+
method: "POST",
|
|
4367
|
+
headers: { ...this.getHeaders(), "Content-Type": "application/json" },
|
|
4368
|
+
body: JSON.stringify({
|
|
4369
|
+
game_type: req.gameType,
|
|
4370
|
+
player_id: req.playerId,
|
|
4371
|
+
rating: req.rating,
|
|
4372
|
+
region: req.region,
|
|
4373
|
+
mode: req.mode,
|
|
4374
|
+
party_members: req.partyMembers,
|
|
4375
|
+
metadata: req.metadata
|
|
4376
|
+
})
|
|
4377
|
+
});
|
|
4378
|
+
if (!response.ok) {
|
|
4379
|
+
const err = await response.json().catch(() => ({}));
|
|
4380
|
+
throw new Error(err.error || `Failed to join queue: ${response.statusText}`);
|
|
4381
|
+
}
|
|
4382
|
+
const data = await response.json();
|
|
4383
|
+
return {
|
|
4384
|
+
ticketId: data.ticket_id,
|
|
4385
|
+
gameType: data.game_type,
|
|
4386
|
+
playerId: data.player_id,
|
|
4387
|
+
status: data.status,
|
|
4388
|
+
createdAt: data.created_at
|
|
4389
|
+
};
|
|
4390
|
+
}
|
|
4391
|
+
/**
|
|
4392
|
+
* 매치메이킹 큐에서 탈퇴
|
|
4393
|
+
*/
|
|
4394
|
+
async leaveQueue(ticketId) {
|
|
4395
|
+
const id = this.appId || "";
|
|
4396
|
+
const response = await fetch(`${this.gameServerUrl}/v1/game/${id}/matchmaking/queue`, {
|
|
4397
|
+
method: "DELETE",
|
|
4398
|
+
headers: { ...this.getHeaders(), "Content-Type": "application/json" },
|
|
4399
|
+
body: JSON.stringify({ ticket_id: ticketId })
|
|
4400
|
+
});
|
|
4401
|
+
if (!response.ok) {
|
|
4402
|
+
const err = await response.json().catch(() => ({}));
|
|
4403
|
+
throw new Error(err.error || `Failed to leave queue: ${response.statusText}`);
|
|
4404
|
+
}
|
|
4405
|
+
}
|
|
4406
|
+
/**
|
|
4407
|
+
* 매치메이킹 상태 조회
|
|
4408
|
+
*/
|
|
4409
|
+
async getMatchStatus(params) {
|
|
4410
|
+
const id = this.appId || "";
|
|
4411
|
+
const searchParams = new URLSearchParams();
|
|
4412
|
+
if (params.ticketId) searchParams.set("ticket_id", params.ticketId);
|
|
4413
|
+
if (params.playerId) searchParams.set("player_id", params.playerId);
|
|
4414
|
+
const response = await fetch(`${this.gameServerUrl}/v1/game/${id}/matchmaking/status?${searchParams}`, {
|
|
4415
|
+
headers: this.getHeaders()
|
|
4416
|
+
});
|
|
4417
|
+
if (!response.ok) {
|
|
4418
|
+
const err = await response.json().catch(() => ({}));
|
|
4419
|
+
throw new Error(err.error || `Failed to get match status: ${response.statusText}`);
|
|
4420
|
+
}
|
|
4421
|
+
const data = await response.json();
|
|
4422
|
+
return {
|
|
4423
|
+
ticketId: data.ticket_id,
|
|
4424
|
+
gameType: data.game_type,
|
|
4425
|
+
playerId: "",
|
|
4426
|
+
status: data.status,
|
|
4427
|
+
createdAt: "",
|
|
4428
|
+
waitTime: data.wait_time,
|
|
4429
|
+
matchId: data.match_id,
|
|
4430
|
+
roomId: data.room_id
|
|
4431
|
+
};
|
|
4432
|
+
}
|
|
4433
|
+
// ==================== Lobbies ====================
|
|
4434
|
+
/**
|
|
4435
|
+
* 로비 목록 조회
|
|
4436
|
+
*/
|
|
4437
|
+
async listLobbies() {
|
|
4438
|
+
const id = this.appId || "";
|
|
4439
|
+
const response = await fetch(`${this.gameServerUrl}/v1/game/${id}/lobbies`, {
|
|
4440
|
+
headers: this.getHeaders()
|
|
4441
|
+
});
|
|
4442
|
+
if (!response.ok) {
|
|
4443
|
+
throw new Error(`Failed to list lobbies: ${response.statusText}`);
|
|
4444
|
+
}
|
|
4445
|
+
const data = await response.json();
|
|
4446
|
+
return (data.lobbies || []).map((l) => ({
|
|
4447
|
+
id: l.id,
|
|
4448
|
+
name: l.name,
|
|
4449
|
+
hostId: l.host_id,
|
|
4450
|
+
gameType: l.game_type,
|
|
4451
|
+
playerCount: l.player_count,
|
|
4452
|
+
maxPlayers: l.max_players,
|
|
4453
|
+
hasPassword: l.has_password,
|
|
4454
|
+
visibility: l.visibility,
|
|
4455
|
+
region: l.region,
|
|
4456
|
+
settings: l.settings,
|
|
4457
|
+
tags: l.tags,
|
|
4458
|
+
status: l.status,
|
|
4459
|
+
createdAt: l.created_at
|
|
4460
|
+
}));
|
|
4461
|
+
}
|
|
4462
|
+
/**
|
|
4463
|
+
* 로비 생성
|
|
4464
|
+
*/
|
|
4465
|
+
async createLobby(req) {
|
|
4466
|
+
const id = this.appId || "";
|
|
4467
|
+
const response = await fetch(`${this.gameServerUrl}/v1/game/${id}/lobbies`, {
|
|
4468
|
+
method: "POST",
|
|
4469
|
+
headers: { ...this.getHeaders(), "Content-Type": "application/json" },
|
|
4470
|
+
body: JSON.stringify({
|
|
4471
|
+
player_id: req.playerId,
|
|
4472
|
+
display_name: req.displayName,
|
|
4473
|
+
name: req.name,
|
|
4474
|
+
game_type: req.gameType,
|
|
4475
|
+
password: req.password,
|
|
4476
|
+
max_players: req.maxPlayers,
|
|
4477
|
+
visibility: req.visibility,
|
|
4478
|
+
region: req.region,
|
|
4479
|
+
settings: req.settings,
|
|
4480
|
+
tags: req.tags
|
|
4481
|
+
})
|
|
4482
|
+
});
|
|
4483
|
+
if (!response.ok) {
|
|
4484
|
+
const err = await response.json().catch(() => ({}));
|
|
4485
|
+
throw new Error(err.error || `Failed to create lobby: ${response.statusText}`);
|
|
4486
|
+
}
|
|
4487
|
+
const data = await response.json();
|
|
4488
|
+
return {
|
|
4489
|
+
id: data.id,
|
|
4490
|
+
name: data.name,
|
|
4491
|
+
hostId: data.host_id,
|
|
4492
|
+
gameType: data.game_type,
|
|
4493
|
+
playerCount: 1,
|
|
4494
|
+
maxPlayers: data.max_players,
|
|
4495
|
+
hasPassword: !!req.password,
|
|
4496
|
+
visibility: data.visibility,
|
|
4497
|
+
region: data.region,
|
|
4498
|
+
settings: data.settings,
|
|
4499
|
+
tags: data.tags,
|
|
4500
|
+
status: data.status,
|
|
4501
|
+
createdAt: data.created_at
|
|
4502
|
+
};
|
|
4503
|
+
}
|
|
4504
|
+
/**
|
|
4505
|
+
* 로비 상세 조회
|
|
4506
|
+
*/
|
|
4507
|
+
async getLobby(lobbyId) {
|
|
4508
|
+
const id = this.appId || "";
|
|
4509
|
+
const response = await fetch(`${this.gameServerUrl}/v1/game/${id}/lobbies/${lobbyId}`, {
|
|
4510
|
+
headers: this.getHeaders()
|
|
4511
|
+
});
|
|
4512
|
+
if (!response.ok) {
|
|
4513
|
+
throw new Error(`Failed to get lobby: ${response.statusText}`);
|
|
4514
|
+
}
|
|
4515
|
+
const data = await response.json();
|
|
4516
|
+
return {
|
|
4517
|
+
id: data.id,
|
|
4518
|
+
name: data.name,
|
|
4519
|
+
hostId: data.host_id,
|
|
4520
|
+
gameType: data.game_type,
|
|
4521
|
+
playerCount: data.player_count,
|
|
4522
|
+
maxPlayers: data.max_players,
|
|
4523
|
+
hasPassword: data.has_password,
|
|
4524
|
+
visibility: data.visibility,
|
|
4525
|
+
region: data.region,
|
|
4526
|
+
settings: data.settings,
|
|
4527
|
+
tags: data.tags,
|
|
4528
|
+
status: data.status,
|
|
4529
|
+
roomId: data.room_id,
|
|
4530
|
+
members: (data.members || []).map((m) => ({
|
|
4531
|
+
playerId: m.player_id,
|
|
4532
|
+
displayName: m.display_name,
|
|
4533
|
+
role: m.role,
|
|
4534
|
+
team: m.team,
|
|
4535
|
+
ready: m.ready,
|
|
4536
|
+
slot: m.slot,
|
|
4537
|
+
joinedAt: m.joined_at
|
|
4538
|
+
})),
|
|
4539
|
+
createdAt: data.created_at
|
|
4540
|
+
};
|
|
4541
|
+
}
|
|
4542
|
+
/**
|
|
4543
|
+
* 로비 참가
|
|
4544
|
+
*/
|
|
4545
|
+
async joinLobby(lobbyId, playerId, displayName, password) {
|
|
4546
|
+
const id = this.appId || "";
|
|
4547
|
+
const response = await fetch(`${this.gameServerUrl}/v1/game/${id}/lobbies/${lobbyId}/join`, {
|
|
4548
|
+
method: "POST",
|
|
4549
|
+
headers: { ...this.getHeaders(), "Content-Type": "application/json" },
|
|
4550
|
+
body: JSON.stringify({ player_id: playerId, display_name: displayName, password })
|
|
4551
|
+
});
|
|
4552
|
+
if (!response.ok) {
|
|
4553
|
+
const err = await response.json().catch(() => ({}));
|
|
4554
|
+
throw new Error(err.error || `Failed to join lobby: ${response.statusText}`);
|
|
4555
|
+
}
|
|
4556
|
+
const data = await response.json();
|
|
4557
|
+
return { lobbyId: data.lobby_id };
|
|
4558
|
+
}
|
|
4559
|
+
/**
|
|
4560
|
+
* 로비 퇴장
|
|
4561
|
+
*/
|
|
4562
|
+
async leaveLobby(lobbyId, playerId) {
|
|
4563
|
+
const id = this.appId || "";
|
|
4564
|
+
const response = await fetch(`${this.gameServerUrl}/v1/game/${id}/lobbies/${lobbyId}/leave`, {
|
|
4565
|
+
method: "POST",
|
|
4566
|
+
headers: { ...this.getHeaders(), "Content-Type": "application/json" },
|
|
4567
|
+
body: JSON.stringify({ player_id: playerId })
|
|
4568
|
+
});
|
|
4569
|
+
if (!response.ok) {
|
|
4570
|
+
const err = await response.json().catch(() => ({}));
|
|
4571
|
+
throw new Error(err.error || `Failed to leave lobby: ${response.statusText}`);
|
|
4572
|
+
}
|
|
4573
|
+
}
|
|
4574
|
+
/**
|
|
4575
|
+
* 레디 상태 토글
|
|
4576
|
+
*/
|
|
4577
|
+
async toggleReady(lobbyId, playerId, ready) {
|
|
4578
|
+
const id = this.appId || "";
|
|
4579
|
+
const response = await fetch(`${this.gameServerUrl}/v1/game/${id}/lobbies/${lobbyId}/ready`, {
|
|
4580
|
+
method: "POST",
|
|
4581
|
+
headers: { ...this.getHeaders(), "Content-Type": "application/json" },
|
|
4582
|
+
body: JSON.stringify({ player_id: playerId, ready })
|
|
4583
|
+
});
|
|
4584
|
+
if (!response.ok) {
|
|
4585
|
+
const err = await response.json().catch(() => ({}));
|
|
4586
|
+
throw new Error(err.error || `Failed to toggle ready: ${response.statusText}`);
|
|
4587
|
+
}
|
|
4588
|
+
}
|
|
4589
|
+
/**
|
|
4590
|
+
* 게임 시작 (호스트만)
|
|
4591
|
+
*/
|
|
4592
|
+
async startGame(lobbyId, hostId) {
|
|
4593
|
+
const id = this.appId || "";
|
|
4594
|
+
const response = await fetch(`${this.gameServerUrl}/v1/game/${id}/lobbies/${lobbyId}/start`, {
|
|
4595
|
+
method: "POST",
|
|
4596
|
+
headers: { ...this.getHeaders(), "Content-Type": "application/json" },
|
|
4597
|
+
body: JSON.stringify({ host_id: hostId })
|
|
4598
|
+
});
|
|
4599
|
+
if (!response.ok) {
|
|
4600
|
+
const err = await response.json().catch(() => ({}));
|
|
4601
|
+
throw new Error(err.error || `Failed to start game: ${response.statusText}`);
|
|
4602
|
+
}
|
|
4603
|
+
const data = await response.json();
|
|
4604
|
+
return { roomId: data.room_id };
|
|
4605
|
+
}
|
|
4606
|
+
/**
|
|
4607
|
+
* 플레이어 추방 (호스트만)
|
|
4608
|
+
*/
|
|
4609
|
+
async kickPlayer(lobbyId, hostId, targetPlayerId) {
|
|
4610
|
+
const id = this.appId || "";
|
|
4611
|
+
const response = await fetch(`${this.gameServerUrl}/v1/game/${id}/lobbies/${lobbyId}/kick/${targetPlayerId}`, {
|
|
4612
|
+
method: "POST",
|
|
4613
|
+
headers: { ...this.getHeaders(), "Content-Type": "application/json" },
|
|
4614
|
+
body: JSON.stringify({ host_id: hostId })
|
|
4615
|
+
});
|
|
4616
|
+
if (!response.ok) {
|
|
4617
|
+
const err = await response.json().catch(() => ({}));
|
|
4618
|
+
throw new Error(err.error || `Failed to kick player: ${response.statusText}`);
|
|
4619
|
+
}
|
|
4620
|
+
}
|
|
4621
|
+
/**
|
|
4622
|
+
* 로비 설정 업데이트 (호스트만)
|
|
4623
|
+
*/
|
|
4624
|
+
async updateLobby(lobbyId, req) {
|
|
4625
|
+
const id = this.appId || "";
|
|
4626
|
+
const response = await fetch(`${this.gameServerUrl}/v1/game/${id}/lobbies/${lobbyId}`, {
|
|
4627
|
+
method: "PATCH",
|
|
4628
|
+
headers: { ...this.getHeaders(), "Content-Type": "application/json" },
|
|
4629
|
+
body: JSON.stringify({
|
|
4630
|
+
host_id: req.hostId,
|
|
4631
|
+
name: req.name,
|
|
4632
|
+
max_players: req.maxPlayers,
|
|
4633
|
+
visibility: req.visibility,
|
|
4634
|
+
password: req.password,
|
|
4635
|
+
settings: req.settings,
|
|
4636
|
+
tags: req.tags
|
|
4637
|
+
})
|
|
4638
|
+
});
|
|
4639
|
+
if (!response.ok) {
|
|
4640
|
+
const err = await response.json().catch(() => ({}));
|
|
4641
|
+
throw new Error(err.error || `Failed to update lobby: ${response.statusText}`);
|
|
4642
|
+
}
|
|
4643
|
+
const data = await response.json();
|
|
4644
|
+
return {
|
|
4645
|
+
id: data.id,
|
|
4646
|
+
name: data.name,
|
|
4647
|
+
hostId: "",
|
|
4648
|
+
gameType: "",
|
|
4649
|
+
playerCount: 0,
|
|
4650
|
+
maxPlayers: data.max_players,
|
|
4651
|
+
hasPassword: false,
|
|
4652
|
+
visibility: data.visibility,
|
|
4653
|
+
region: "",
|
|
4654
|
+
settings: data.settings,
|
|
4655
|
+
tags: data.tags,
|
|
4656
|
+
status: "",
|
|
4657
|
+
createdAt: ""
|
|
4658
|
+
};
|
|
4659
|
+
}
|
|
4660
|
+
/**
|
|
4661
|
+
* 로비 채팅 전송
|
|
4662
|
+
*/
|
|
4663
|
+
async sendLobbyChat(lobbyId, playerId, message) {
|
|
4664
|
+
const id = this.appId || "";
|
|
4665
|
+
const response = await fetch(`${this.gameServerUrl}/v1/game/${id}/lobbies/${lobbyId}/chat`, {
|
|
4666
|
+
method: "POST",
|
|
4667
|
+
headers: { ...this.getHeaders(), "Content-Type": "application/json" },
|
|
4668
|
+
body: JSON.stringify({ player_id: playerId, message })
|
|
4669
|
+
});
|
|
4670
|
+
if (!response.ok) {
|
|
4671
|
+
const err = await response.json().catch(() => ({}));
|
|
4672
|
+
throw new Error(err.error || `Failed to send chat: ${response.statusText}`);
|
|
4673
|
+
}
|
|
4674
|
+
}
|
|
4675
|
+
/**
|
|
4676
|
+
* 플레이어 초대
|
|
4677
|
+
*/
|
|
4678
|
+
async invitePlayer(lobbyId, inviterId, inviteeId) {
|
|
4679
|
+
const id = this.appId || "";
|
|
4680
|
+
const response = await fetch(`${this.gameServerUrl}/v1/game/${id}/lobbies/${lobbyId}/invite`, {
|
|
4681
|
+
method: "POST",
|
|
4682
|
+
headers: { ...this.getHeaders(), "Content-Type": "application/json" },
|
|
4683
|
+
body: JSON.stringify({ inviter_id: inviterId, invitee_id: inviteeId })
|
|
4684
|
+
});
|
|
4685
|
+
if (!response.ok) {
|
|
4686
|
+
const err = await response.json().catch(() => ({}));
|
|
4687
|
+
throw new Error(err.error || `Failed to invite player: ${response.statusText}`);
|
|
4688
|
+
}
|
|
4689
|
+
const data = await response.json();
|
|
4690
|
+
return {
|
|
4691
|
+
inviteId: data.invite_id,
|
|
4692
|
+
lobbyId: data.lobby_id,
|
|
4693
|
+
lobbyName: data.lobby_name,
|
|
4694
|
+
inviterId: data.inviter_id,
|
|
4695
|
+
inviteeId: data.invitee_id,
|
|
4696
|
+
status: "pending",
|
|
4697
|
+
createdAt: "",
|
|
4698
|
+
expiresAt: data.expires_at
|
|
4699
|
+
};
|
|
4700
|
+
}
|
|
4701
|
+
/**
|
|
4702
|
+
* 초대 수락
|
|
4703
|
+
*/
|
|
4704
|
+
async acceptInvite(inviteId, playerId, displayName) {
|
|
4705
|
+
const id = this.appId || "";
|
|
4706
|
+
const response = await fetch(`${this.gameServerUrl}/v1/game/${id}/lobbies/invites/${inviteId}/accept`, {
|
|
4707
|
+
method: "POST",
|
|
4708
|
+
headers: { ...this.getHeaders(), "Content-Type": "application/json" },
|
|
4709
|
+
body: JSON.stringify({ player_id: playerId, display_name: displayName })
|
|
4710
|
+
});
|
|
4711
|
+
if (!response.ok) {
|
|
4712
|
+
const err = await response.json().catch(() => ({}));
|
|
4713
|
+
throw new Error(err.error || `Failed to accept invite: ${response.statusText}`);
|
|
4714
|
+
}
|
|
4715
|
+
const data = await response.json();
|
|
4716
|
+
return { lobbyId: data.lobby_id };
|
|
4717
|
+
}
|
|
4718
|
+
/**
|
|
4719
|
+
* 초대 거절
|
|
4720
|
+
*/
|
|
4721
|
+
async declineInvite(inviteId, playerId) {
|
|
4722
|
+
const id = this.appId || "";
|
|
4723
|
+
const response = await fetch(`${this.gameServerUrl}/v1/game/${id}/lobbies/invites/${inviteId}/decline`, {
|
|
4724
|
+
method: "POST",
|
|
4725
|
+
headers: { ...this.getHeaders(), "Content-Type": "application/json" },
|
|
4726
|
+
body: JSON.stringify({ player_id: playerId })
|
|
4727
|
+
});
|
|
4728
|
+
if (!response.ok) {
|
|
4729
|
+
const err = await response.json().catch(() => ({}));
|
|
4730
|
+
throw new Error(err.error || `Failed to decline invite: ${response.statusText}`);
|
|
4731
|
+
}
|
|
4732
|
+
}
|
|
4733
|
+
/**
|
|
4734
|
+
* 플레이어의 받은 초대 목록
|
|
4735
|
+
*/
|
|
4736
|
+
async getPlayerInvites(playerId) {
|
|
4737
|
+
const id = this.appId || "";
|
|
4738
|
+
const response = await fetch(`${this.gameServerUrl}/v1/game/${id}/lobbies/player/${playerId}/invites`, {
|
|
4739
|
+
headers: this.getHeaders()
|
|
4740
|
+
});
|
|
4741
|
+
if (!response.ok) {
|
|
4742
|
+
throw new Error(`Failed to get invites: ${response.statusText}`);
|
|
4743
|
+
}
|
|
4744
|
+
const data = await response.json();
|
|
4745
|
+
return (data.invites || []).map((inv) => ({
|
|
4746
|
+
inviteId: inv.invite_id,
|
|
4747
|
+
lobbyId: inv.lobby_id,
|
|
4748
|
+
lobbyName: inv.lobby_name,
|
|
4749
|
+
inviterId: inv.inviter_id,
|
|
4750
|
+
inviteeId: "",
|
|
4751
|
+
status: inv.status,
|
|
4752
|
+
createdAt: inv.created_at,
|
|
4753
|
+
expiresAt: inv.expires_at
|
|
4754
|
+
}));
|
|
4755
|
+
}
|
|
4359
4756
|
getHeaders() {
|
|
4360
4757
|
const headers = {};
|
|
4361
4758
|
const apiKey = this.http.getApiKey();
|