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