@gbraver-burst-network/local-webrtc-browser-sdk 1.20.0-beta.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.
Files changed (85) hide show
  1. package/LICENSE.txt +7 -0
  2. package/Readme.md +37 -0
  3. package/lib/index.d.ts +4 -0
  4. package/lib/index.js +7 -0
  5. package/lib/json/parse.d.ts +7 -0
  6. package/lib/json/parse.js +20 -0
  7. package/lib/sdk/battle-sdk.d.ts +25 -0
  8. package/lib/sdk/battle-sdk.js +2 -0
  9. package/lib/sdk/guest-battle-sdk.d.ts +39 -0
  10. package/lib/sdk/guest-battle-sdk.js +73 -0
  11. package/lib/sdk/guest-webrtc-connection-manager.d.ts +19 -0
  12. package/lib/sdk/guest-webrtc-connection-manager.js +52 -0
  13. package/lib/sdk/host-battle-sdk.d.ts +39 -0
  14. package/lib/sdk/host-battle-sdk.js +97 -0
  15. package/lib/sdk/host-webrtc-connection-manager.d.ts +19 -0
  16. package/lib/sdk/host-webrtc-connection-manager.js +51 -0
  17. package/lib/sdk/local-webrtc-guest-sdk.d.ts +34 -0
  18. package/lib/sdk/local-webrtc-guest-sdk.js +136 -0
  19. package/lib/sdk/local-webrtc-host-sdk.d.ts +32 -0
  20. package/lib/sdk/local-webrtc-host-sdk.js +93 -0
  21. package/lib/sdk/local-webrtc-room.d.ts +39 -0
  22. package/lib/sdk/local-webrtc-room.js +106 -0
  23. package/lib/sdk/websocket-connection-manager.d.ts +27 -0
  24. package/lib/sdk/websocket-connection-manager.js +84 -0
  25. package/lib/webrtc/guest/guest-message.d.ts +48 -0
  26. package/lib/webrtc/guest/guest-message.js +27 -0
  27. package/lib/webrtc/guest/receive-battle-progressed.d.ts +7 -0
  28. package/lib/webrtc/guest/receive-battle-progressed.js +29 -0
  29. package/lib/webrtc/guest/receive-battle-start.d.ts +7 -0
  30. package/lib/webrtc/guest/receive-battle-start.js +29 -0
  31. package/lib/webrtc/guest/receive-request-selected-player.d.ts +7 -0
  32. package/lib/webrtc/guest/receive-request-selected-player.js +29 -0
  33. package/lib/webrtc/guest/wait-until-data-channel.d.ts +6 -0
  34. package/lib/webrtc/guest/wait-until-data-channel.js +14 -0
  35. package/lib/webrtc/host/host-message.d.ts +1001 -0
  36. package/lib/webrtc/host/host-message.js +33 -0
  37. package/lib/webrtc/host/receive-send-command.d.ts +8 -0
  38. package/lib/webrtc/host/receive-send-command.js +31 -0
  39. package/lib/webrtc/host/request-selected-player.d.ts +16 -0
  40. package/lib/webrtc/host/request-selected-player.js +35 -0
  41. package/lib/webrtc/rtc-ice-candidate-init-schema.d.ts +8 -0
  42. package/lib/webrtc/rtc-ice-candidate-init-schema.js +11 -0
  43. package/lib/webrtc/rtc-session-description-init-schema.d.ts +11 -0
  44. package/lib/webrtc/rtc-session-description-init-schema.js +9 -0
  45. package/lib/webrtc/signal.d.ts +5 -0
  46. package/lib/webrtc/signal.js +2 -0
  47. package/lib/webrtc/wait-until-connected.d.ts +6 -0
  48. package/lib/webrtc/wait-until-connected.js +28 -0
  49. package/lib/webrtc/wait-until-data-channel-ready.d.ts +6 -0
  50. package/lib/webrtc/wait-until-data-channel-ready.js +28 -0
  51. package/lib/webrtc/wait-untilIce-candidate.d.ts +6 -0
  52. package/lib/webrtc/wait-untilIce-candidate.js +28 -0
  53. package/lib/ws-signal/connect-ws-signal.d.ts +6 -0
  54. package/lib/ws-signal/connect-ws-signal.js +28 -0
  55. package/lib/ws-signal/create-room.d.ts +13 -0
  56. package/lib/ws-signal/create-room.js +41 -0
  57. package/lib/ws-signal/join-room.d.ts +12 -0
  58. package/lib/ws-signal/join-room.js +40 -0
  59. package/lib/ws-signal/request/create-room.d.ts +8 -0
  60. package/lib/ws-signal/request/create-room.js +2 -0
  61. package/lib/ws-signal/request/index.d.ts +5 -0
  62. package/lib/ws-signal/request/index.js +2 -0
  63. package/lib/ws-signal/request/join-room.d.ts +6 -0
  64. package/lib/ws-signal/request/join-room.js +2 -0
  65. package/lib/ws-signal/request/send-guest-signal.d.ts +12 -0
  66. package/lib/ws-signal/request/send-guest-signal.js +2 -0
  67. package/lib/ws-signal/response/join-room-accepted.d.ts +31 -0
  68. package/lib/ws-signal/response/join-room-accepted.js +13 -0
  69. package/lib/ws-signal/response/join-room-rejected.d.ts +9 -0
  70. package/lib/ws-signal/response/join-room-rejected.js +8 -0
  71. package/lib/ws-signal/response/matching.d.ts +28 -0
  72. package/lib/ws-signal/response/matching.js +12 -0
  73. package/lib/ws-signal/response/room-creation-result.d.ts +37 -0
  74. package/lib/ws-signal/response/room-creation-result.js +20 -0
  75. package/lib/ws-signal/response/send-guest-signal-accepted.d.ts +9 -0
  76. package/lib/ws-signal/response/send-guest-signal-accepted.js +8 -0
  77. package/lib/ws-signal/response/send-guest-signal-rejected.d.ts +9 -0
  78. package/lib/ws-signal/response/send-guest-signal-rejected.js +8 -0
  79. package/lib/ws-signal/send-guest-signal.d.ts +17 -0
  80. package/lib/ws-signal/send-guest-signal.js +49 -0
  81. package/lib/ws-signal/send-to-ws-signal.d.ts +7 -0
  82. package/lib/ws-signal/send-to-ws-signal.js +11 -0
  83. package/lib/ws-signal/wait-until-matching.d.ts +7 -0
  84. package/lib/ws-signal/wait-until-matching.js +30 -0
  85. package/package.json +52 -0
@@ -0,0 +1,136 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
12
+ if (kind === "m") throw new TypeError("Private method is not writable");
13
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
14
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
15
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
16
+ };
17
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
18
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
19
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
20
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
21
+ };
22
+ var _LocalWebRTCGuestSDKImpl_instances, _LocalWebRTCGuestSDKImpl_webRTCConnection, _LocalWebRTCGuestSDKImpl_websocketConnection, _LocalWebRTCGuestSDKImpl_signaling;
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ exports.createLocalWebRTCGuestSDK = createLocalWebRTCGuestSDK;
25
+ const guest_message_1 = require("../webrtc/guest/guest-message");
26
+ const receive_battle_start_1 = require("../webrtc/guest/receive-battle-start");
27
+ const receive_request_selected_player_1 = require("../webrtc/guest/receive-request-selected-player");
28
+ const wait_until_connected_1 = require("../webrtc/wait-until-connected");
29
+ const wait_untilIce_candidate_1 = require("../webrtc/wait-untilIce-candidate");
30
+ const join_room_1 = require("../ws-signal/join-room");
31
+ const send_guest_signal_1 = require("../ws-signal/send-guest-signal");
32
+ const guest_battle_sdk_1 = require("./guest-battle-sdk");
33
+ const guest_webrtc_connection_manager_1 = require("./guest-webrtc-connection-manager");
34
+ const websocket_connection_manager_1 = require("./websocket-connection-manager");
35
+ /** ローカルWebRTCゲスト用SDKの実装 */
36
+ class LocalWebRTCGuestSDKImpl {
37
+ /**
38
+ * コンストラクタ
39
+ * @param wsSignalUrl WebSocketシグナルサーバーのURL
40
+ */
41
+ constructor(wsSignalUrl) {
42
+ _LocalWebRTCGuestSDKImpl_instances.add(this);
43
+ /** WebRTCコネクションマネージャー */
44
+ _LocalWebRTCGuestSDKImpl_webRTCConnection.set(this, void 0);
45
+ /** WebSocketコネクションマネージャー */
46
+ _LocalWebRTCGuestSDKImpl_websocketConnection.set(this, void 0);
47
+ __classPrivateFieldSet(this, _LocalWebRTCGuestSDKImpl_webRTCConnection, new guest_webrtc_connection_manager_1.GuestWebRTCConnectionManager(), "f");
48
+ __classPrivateFieldSet(this, _LocalWebRTCGuestSDKImpl_websocketConnection, new websocket_connection_manager_1.WebSocketConnectionManager(wsSignalUrl), "f");
49
+ }
50
+ /** @override */
51
+ joinRoom(options) {
52
+ return __awaiter(this, void 0, void 0, function* () {
53
+ const { roomID, armdozerId, pilotId } = options;
54
+ const requestSelectedPlayerPromise = (() => __awaiter(this, void 0, void 0, function* () {
55
+ const dataChannel = yield __classPrivateFieldGet(this, _LocalWebRTCGuestSDKImpl_webRTCConnection, "f").getOrCreateConnection().dataChannel;
56
+ return yield (0, receive_request_selected_player_1.receiveRequestSelectedPlayer)(dataChannel);
57
+ }))();
58
+ const battleStartPromise = (() => __awaiter(this, void 0, void 0, function* () {
59
+ const dataChannel = yield __classPrivateFieldGet(this, _LocalWebRTCGuestSDKImpl_webRTCConnection, "f").getOrCreateConnection().dataChannel;
60
+ return yield (0, receive_battle_start_1.receiveBattleStart)(dataChannel);
61
+ }))();
62
+ const isSignalingSuccessful = yield __classPrivateFieldGet(this, _LocalWebRTCGuestSDKImpl_instances, "m", _LocalWebRTCGuestSDKImpl_signaling).call(this, roomID);
63
+ if (!isSignalingSuccessful) {
64
+ return null;
65
+ }
66
+ const { flowID } = yield requestSelectedPlayerPromise;
67
+ const dataChannel = yield __classPrivateFieldGet(this, _LocalWebRTCGuestSDKImpl_webRTCConnection, "f").getOrCreateConnection().dataChannel;
68
+ (0, guest_message_1.sendGuestMessage)(dataChannel, {
69
+ type: "send-player",
70
+ flowID,
71
+ armdozerId,
72
+ pilotId,
73
+ });
74
+ const battleStart = yield battleStartPromise;
75
+ return new guest_battle_sdk_1.GuestBattleSDK({
76
+ hostPlayer: battleStart.hostPlayer,
77
+ guestPlayer: battleStart.guestPlayer,
78
+ initialState: battleStart.update,
79
+ initialFlowID: battleStart.flowID,
80
+ webRTCConnection: __classPrivateFieldGet(this, _LocalWebRTCGuestSDKImpl_webRTCConnection, "f"),
81
+ });
82
+ });
83
+ }
84
+ /** @override */
85
+ websocketErrorNotifier() {
86
+ return __classPrivateFieldGet(this, _LocalWebRTCGuestSDKImpl_websocketConnection, "f").errorNotifier();
87
+ }
88
+ /** @override */
89
+ disconnectWebRTC() {
90
+ __classPrivateFieldGet(this, _LocalWebRTCGuestSDKImpl_webRTCConnection, "f").disconnect();
91
+ }
92
+ }
93
+ _LocalWebRTCGuestSDKImpl_webRTCConnection = new WeakMap(), _LocalWebRTCGuestSDKImpl_websocketConnection = new WeakMap(), _LocalWebRTCGuestSDKImpl_instances = new WeakSet(), _LocalWebRTCGuestSDKImpl_signaling = function _LocalWebRTCGuestSDKImpl_signaling(roomID) {
94
+ return __awaiter(this, void 0, void 0, function* () {
95
+ try {
96
+ const websocket = yield __classPrivateFieldGet(this, _LocalWebRTCGuestSDKImpl_websocketConnection, "f").getOrCreate();
97
+ const joinRoomAccepted = yield (0, join_room_1.joinRoom)({ websocket, roomID });
98
+ if (!joinRoomAccepted) {
99
+ return false;
100
+ }
101
+ const { sdp: hostSDP, iceCandidates: hostIceCandidates } = joinRoomAccepted;
102
+ const { connection } = __classPrivateFieldGet(this, _LocalWebRTCGuestSDKImpl_webRTCConnection, "f").getOrCreateConnection();
103
+ yield connection.setRemoteDescription(hostSDP);
104
+ yield Promise.all(hostIceCandidates.map((c) => connection.addIceCandidate(c)));
105
+ const guestSDP = yield connection.createAnswer();
106
+ const [guestIceCandidates] = yield Promise.all([
107
+ // icecandidateイベントはsetLocalDescriptionの後に発生するため、先に待機しておく
108
+ (0, wait_untilIce_candidate_1.waitUntilIceCandidate)(connection),
109
+ connection.setLocalDescription(guestSDP),
110
+ ]);
111
+ const { reservationID } = joinRoomAccepted;
112
+ yield Promise.all([
113
+ (0, send_guest_signal_1.sendGuestSignal)({
114
+ websocket,
115
+ roomID,
116
+ reservationID,
117
+ sdp: guestSDP,
118
+ iceCandidates: guestIceCandidates,
119
+ }),
120
+ (0, wait_until_connected_1.waitUntilConnected)(connection),
121
+ ]);
122
+ return true;
123
+ }
124
+ finally {
125
+ __classPrivateFieldGet(this, _LocalWebRTCGuestSDKImpl_websocketConnection, "f").gracefulDisconnect();
126
+ }
127
+ });
128
+ };
129
+ /**
130
+ * ローカルWebRTCゲスト用SDKを生成する
131
+ * @param wsSignalUrl WebSocketシグナルサーバーのURL
132
+ * @returns ローカルWebRTCゲスト用SDKのインスタンス
133
+ */
134
+ function createLocalWebRTCGuestSDK(wsSignalUrl) {
135
+ return new LocalWebRTCGuestSDKImpl(wsSignalUrl);
136
+ }
@@ -0,0 +1,32 @@
1
+ import { ArmdozerId, PilotId } from "gbraver-burst-core";
2
+ import { Observable } from "rxjs";
3
+ import { LocalWebRTCRoom } from "./local-webrtc-room";
4
+ /** ローカルWebRTCホスト用SDK */
5
+ export type LocalWebRTCHostSDK = {
6
+ /**
7
+ * ルームを生成する
8
+ * @param options ルーム生成のオプション
9
+ * @param options.armdozerId ホストが選択したアームドーザのID
10
+ * @param options.pilotId ホストが選択したパイロットのID
11
+ * @returns 生成されたルーム、生成に失敗した場合はnull
12
+ */
13
+ createRoom: (options: {
14
+ armdozerId: ArmdozerId;
15
+ pilotId: PilotId;
16
+ }) => Promise<LocalWebRTCRoom | null>;
17
+ /**
18
+ * WebSocketのエラーを通知する
19
+ * @returns 通知ストリーム
20
+ */
21
+ websocketErrorNotifier(): Observable<unknown>;
22
+ /**
23
+ * WebRTCコネクションを切断する
24
+ */
25
+ disconnectWebRTC(): void;
26
+ };
27
+ /**
28
+ * ローカルWebRTCホスト用SDKを生成する
29
+ * @param wsSignalUrl WebSocketシグナルサーバーのURL
30
+ * @returns ローカルWebRTCホスト用SDKのインスタンス
31
+ */
32
+ export declare function createLocalWebRTCHostSDK(wsSignalUrl: string): LocalWebRTCHostSDK;
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
12
+ if (kind === "m") throw new TypeError("Private method is not writable");
13
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
14
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
15
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
16
+ };
17
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
18
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
19
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
20
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
21
+ };
22
+ var _LocalWebRTCHostSDKImpl_webRTCConnection, _LocalWebRTCHostSDKImpl_websocketConnection;
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ exports.createLocalWebRTCHostSDK = createLocalWebRTCHostSDK;
25
+ const wait_untilIce_candidate_1 = require("../webrtc/wait-untilIce-candidate");
26
+ const create_room_1 = require("../ws-signal/create-room");
27
+ const host_webrtc_connection_manager_1 = require("./host-webrtc-connection-manager");
28
+ const local_webrtc_room_1 = require("./local-webrtc-room");
29
+ const websocket_connection_manager_1 = require("./websocket-connection-manager");
30
+ /** ローカルWebRTCホスト用SDKの実装 */
31
+ class LocalWebRTCHostSDKImpl {
32
+ /**
33
+ * コンストラクタ
34
+ * @param wsSignalUrl WebSocketシグナルサーバーのURL
35
+ */
36
+ constructor(wsSignalUrl) {
37
+ /** WebRTCコネクションマネージャー */
38
+ _LocalWebRTCHostSDKImpl_webRTCConnection.set(this, void 0);
39
+ /** WebSocketコネクションマネージャー */
40
+ _LocalWebRTCHostSDKImpl_websocketConnection.set(this, void 0);
41
+ __classPrivateFieldSet(this, _LocalWebRTCHostSDKImpl_websocketConnection, new websocket_connection_manager_1.WebSocketConnectionManager(wsSignalUrl), "f");
42
+ __classPrivateFieldSet(this, _LocalWebRTCHostSDKImpl_webRTCConnection, new host_webrtc_connection_manager_1.HostWebRTCConnectionManager(), "f");
43
+ }
44
+ /** @override */
45
+ createRoom(options) {
46
+ return __awaiter(this, void 0, void 0, function* () {
47
+ try {
48
+ const { connection } = __classPrivateFieldGet(this, _LocalWebRTCHostSDKImpl_webRTCConnection, "f").getOrCreateConnection();
49
+ const sdp = yield connection.createOffer();
50
+ const [iceCandidates] = yield Promise.all([
51
+ // icecandidateイベントはsetLocalDescriptionの後に発生するため、先に待機しておく
52
+ (0, wait_untilIce_candidate_1.waitUntilIceCandidate)(connection),
53
+ connection.setLocalDescription(sdp),
54
+ ]);
55
+ const websocket = yield __classPrivateFieldGet(this, _LocalWebRTCHostSDKImpl_websocketConnection, "f").getOrCreate();
56
+ const roomID = yield (0, create_room_1.createRoom)({ websocket, sdp, iceCandidates });
57
+ if (roomID === null) {
58
+ __classPrivateFieldGet(this, _LocalWebRTCHostSDKImpl_websocketConnection, "f").gracefulDisconnect();
59
+ return null;
60
+ }
61
+ const { armdozerId: hostArmdozerId, pilotId: hostPilotId } = options;
62
+ return new local_webrtc_room_1.LocalWebRTCRoomImpl({
63
+ roomID,
64
+ webRTCConnection: __classPrivateFieldGet(this, _LocalWebRTCHostSDKImpl_webRTCConnection, "f"),
65
+ websocketConnection: __classPrivateFieldGet(this, _LocalWebRTCHostSDKImpl_websocketConnection, "f"),
66
+ hostArmdozerId,
67
+ hostPilotId,
68
+ });
69
+ }
70
+ catch (e) {
71
+ __classPrivateFieldGet(this, _LocalWebRTCHostSDKImpl_websocketConnection, "f").gracefulDisconnect();
72
+ throw e;
73
+ }
74
+ });
75
+ }
76
+ /** @override */
77
+ websocketErrorNotifier() {
78
+ return __classPrivateFieldGet(this, _LocalWebRTCHostSDKImpl_websocketConnection, "f").errorNotifier();
79
+ }
80
+ /** @override */
81
+ disconnectWebRTC() {
82
+ __classPrivateFieldGet(this, _LocalWebRTCHostSDKImpl_webRTCConnection, "f").disconnect();
83
+ }
84
+ }
85
+ _LocalWebRTCHostSDKImpl_webRTCConnection = new WeakMap(), _LocalWebRTCHostSDKImpl_websocketConnection = new WeakMap();
86
+ /**
87
+ * ローカルWebRTCホスト用SDKを生成する
88
+ * @param wsSignalUrl WebSocketシグナルサーバーのURL
89
+ * @returns ローカルWebRTCホスト用SDKのインスタンス
90
+ */
91
+ function createLocalWebRTCHostSDK(wsSignalUrl) {
92
+ return new LocalWebRTCHostSDKImpl(wsSignalUrl);
93
+ }
@@ -0,0 +1,39 @@
1
+ import { ArmdozerId, PilotId } from "gbraver-burst-core";
2
+ import { BattleSDK } from "./battle-sdk";
3
+ import { HostWebRTCConnectionManager } from "./host-webrtc-connection-manager";
4
+ import { WebSocketConnectionManager } from "./websocket-connection-manager";
5
+ /** ローカルWebRTC ルーム */
6
+ export type LocalWebRTCRoom = {
7
+ /** ルームID */
8
+ readonly roomID: string;
9
+ /**
10
+ * マッチングするまで待機する
11
+ * @returns マッチングした相手とのバトルSDK
12
+ */
13
+ waitUntilMatching: () => Promise<BattleSDK>;
14
+ };
15
+ /** ローカルWebRTCルームの実装 */
16
+ export declare class LocalWebRTCRoomImpl implements LocalWebRTCRoom {
17
+ #private;
18
+ /** ルームID */
19
+ roomID: string;
20
+ /**
21
+ * コンストラクタ
22
+ * @param options ルームの生成に必要なオプション
23
+ * @param options.roomID ルームID
24
+ * @param options.webRTCConnection WebRTCコネクションマネジャー
25
+ * @param options.websocketConnection WebSocketコネクションマネジャー
26
+ */
27
+ constructor(options: {
28
+ roomID: string;
29
+ webRTCConnection: HostWebRTCConnectionManager;
30
+ websocketConnection: WebSocketConnectionManager;
31
+ hostArmdozerId: ArmdozerId;
32
+ hostPilotId: PilotId;
33
+ });
34
+ /**
35
+ * マッチングするまで待機する
36
+ * @returns マッチングしたら発火するPromise
37
+ */
38
+ waitUntilMatching(): Promise<BattleSDK>;
39
+ }
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
12
+ if (kind === "m") throw new TypeError("Private method is not writable");
13
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
14
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
15
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
16
+ };
17
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
18
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
19
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
20
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
21
+ };
22
+ var _LocalWebRTCRoomImpl_instances, _LocalWebRTCRoomImpl_webRTCConnection, _LocalWebRTCRoomImpl_websocketConnection, _LocalWebRTCRoomImpl_hostArmdozerId, _LocalWebRTCRoomImpl_hostPilotId, _LocalWebRTCRoomImpl_signaling;
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ exports.LocalWebRTCRoomImpl = void 0;
25
+ const nanoid_1 = require("nanoid");
26
+ const host_message_1 = require("../webrtc/host/host-message");
27
+ const request_selected_player_1 = require("../webrtc/host/request-selected-player");
28
+ const wait_until_connected_1 = require("../webrtc/wait-until-connected");
29
+ const wait_until_data_channel_ready_1 = require("../webrtc/wait-until-data-channel-ready");
30
+ const wait_until_matching_1 = require("../ws-signal/wait-until-matching");
31
+ const host_battle_sdk_1 = require("./host-battle-sdk");
32
+ /** ローカルWebRTCルームの実装 */
33
+ class LocalWebRTCRoomImpl {
34
+ /**
35
+ * コンストラクタ
36
+ * @param options ルームの生成に必要なオプション
37
+ * @param options.roomID ルームID
38
+ * @param options.webRTCConnection WebRTCコネクションマネジャー
39
+ * @param options.websocketConnection WebSocketコネクションマネジャー
40
+ */
41
+ constructor(options) {
42
+ _LocalWebRTCRoomImpl_instances.add(this);
43
+ /** WebRTCコネクションマネージャー */
44
+ _LocalWebRTCRoomImpl_webRTCConnection.set(this, void 0);
45
+ /** WebSocketコネクションマネージャー */
46
+ _LocalWebRTCRoomImpl_websocketConnection.set(this, void 0);
47
+ /** ホストが選択したアームドーザID */
48
+ _LocalWebRTCRoomImpl_hostArmdozerId.set(this, void 0);
49
+ /** ホストが選択したパイロットID */
50
+ _LocalWebRTCRoomImpl_hostPilotId.set(this, void 0);
51
+ const { roomID, webRTCConnection, websocketConnection, hostArmdozerId, hostPilotId, } = options;
52
+ this.roomID = roomID;
53
+ __classPrivateFieldSet(this, _LocalWebRTCRoomImpl_webRTCConnection, webRTCConnection, "f");
54
+ __classPrivateFieldSet(this, _LocalWebRTCRoomImpl_websocketConnection, websocketConnection, "f");
55
+ __classPrivateFieldSet(this, _LocalWebRTCRoomImpl_hostArmdozerId, hostArmdozerId, "f");
56
+ __classPrivateFieldSet(this, _LocalWebRTCRoomImpl_hostPilotId, hostPilotId, "f");
57
+ }
58
+ /**
59
+ * マッチングするまで待機する
60
+ * @returns マッチングしたら発火するPromise
61
+ */
62
+ waitUntilMatching() {
63
+ return __awaiter(this, void 0, void 0, function* () {
64
+ const { dataChannel } = __classPrivateFieldGet(this, _LocalWebRTCRoomImpl_webRTCConnection, "f").getOrCreateConnection();
65
+ yield Promise.all([
66
+ __classPrivateFieldGet(this, _LocalWebRTCRoomImpl_instances, "m", _LocalWebRTCRoomImpl_signaling).call(this),
67
+ (0, wait_until_data_channel_ready_1.waitUntilDataChannelOpen)(dataChannel),
68
+ ]);
69
+ const flowID = (0, nanoid_1.nanoid)();
70
+ const { armdozerId: guestArmdozerId, pilotId: guestPilotId } = yield (0, request_selected_player_1.requestSelectedPlayer)(dataChannel, flowID);
71
+ const battleSDK = new host_battle_sdk_1.HostBattleSDK({
72
+ hostArmdozerId: __classPrivateFieldGet(this, _LocalWebRTCRoomImpl_hostArmdozerId, "f"),
73
+ hostPilotId: __classPrivateFieldGet(this, _LocalWebRTCRoomImpl_hostPilotId, "f"),
74
+ guestArmdozerId,
75
+ guestPilotId,
76
+ webRTCConnection: __classPrivateFieldGet(this, _LocalWebRTCRoomImpl_webRTCConnection, "f"),
77
+ });
78
+ (0, host_message_1.sendHostMessage)(dataChannel, {
79
+ type: "battle-start",
80
+ flowID: battleSDK.flowID,
81
+ hostPlayer: battleSDK.player,
82
+ guestPlayer: battleSDK.enemy,
83
+ update: battleSDK.initialState,
84
+ });
85
+ return battleSDK;
86
+ });
87
+ }
88
+ }
89
+ exports.LocalWebRTCRoomImpl = LocalWebRTCRoomImpl;
90
+ _LocalWebRTCRoomImpl_webRTCConnection = new WeakMap(), _LocalWebRTCRoomImpl_websocketConnection = new WeakMap(), _LocalWebRTCRoomImpl_hostArmdozerId = new WeakMap(), _LocalWebRTCRoomImpl_hostPilotId = new WeakMap(), _LocalWebRTCRoomImpl_instances = new WeakSet(), _LocalWebRTCRoomImpl_signaling = function _LocalWebRTCRoomImpl_signaling() {
91
+ return __awaiter(this, void 0, void 0, function* () {
92
+ try {
93
+ const websocket = yield __classPrivateFieldGet(this, _LocalWebRTCRoomImpl_websocketConnection, "f").getOrCreate();
94
+ const signal = yield (0, wait_until_matching_1.waitUntilMatching)(websocket);
95
+ const { connection } = __classPrivateFieldGet(this, _LocalWebRTCRoomImpl_webRTCConnection, "f").getOrCreateConnection();
96
+ yield connection.setRemoteDescription(signal.sdp);
97
+ yield Promise.all([
98
+ ...signal.iceCandidates.map((c) => connection.addIceCandidate(c)),
99
+ ]);
100
+ yield (0, wait_until_connected_1.waitUntilConnected)(connection);
101
+ }
102
+ finally {
103
+ __classPrivateFieldGet(this, _LocalWebRTCRoomImpl_websocketConnection, "f").gracefulDisconnect();
104
+ }
105
+ });
106
+ };
@@ -0,0 +1,27 @@
1
+ import { Observable } from "rxjs";
2
+ export declare class WebSocketConnectionManager {
3
+ #private;
4
+ /** WebSocketシグナルサーバーのURL */
5
+ readonly wsSignalUrl: string;
6
+ /**
7
+ * コンストラクタ
8
+ * @param wsSignalUrl WebSocketシグナルサーバーのURL
9
+ */
10
+ constructor(wsSignalUrl: string);
11
+ /**
12
+ * WebSocketクライアントの取得を行う
13
+ * WebSocketクライアントが存在しない場合は、本メソッド内で生成してから返す
14
+ * @returns 取得、生成結果
15
+ */
16
+ getOrCreate(): Promise<WebSocket>;
17
+ /**
18
+ * Websocketコネクションを切断する
19
+ * 本メソッドを呼び出すことで、WebSocketコネクションに関連するイベントストリームの購読も解除する
20
+ */
21
+ gracefulDisconnect(): void;
22
+ /**
23
+ * WebSocketのエラーを通知する
24
+ * @returns 通知ストリーム
25
+ */
26
+ errorNotifier(): Observable<unknown>;
27
+ }
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
12
+ if (kind === "m") throw new TypeError("Private method is not writable");
13
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
14
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
15
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
16
+ };
17
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
18
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
19
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
20
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
21
+ };
22
+ var _WebSocketConnectionManager_websocket, _WebSocketConnectionManager_websocketError, _WebSocketConnectionManager_websocketSubscriptions;
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ exports.WebSocketConnectionManager = void 0;
25
+ const rxjs_1 = require("rxjs");
26
+ const connect_ws_signal_1 = require("../ws-signal/connect-ws-signal");
27
+ class WebSocketConnectionManager {
28
+ /**
29
+ * コンストラクタ
30
+ * @param wsSignalUrl WebSocketシグナルサーバーのURL
31
+ */
32
+ constructor(wsSignalUrl) {
33
+ /** WebSocketコネクション */
34
+ _WebSocketConnectionManager_websocket.set(this, null);
35
+ /** Web Socket エラー通知 */
36
+ _WebSocketConnectionManager_websocketError.set(this, void 0);
37
+ /** Web Socket イベントストリーム */
38
+ _WebSocketConnectionManager_websocketSubscriptions.set(this, void 0);
39
+ this.wsSignalUrl = wsSignalUrl;
40
+ __classPrivateFieldSet(this, _WebSocketConnectionManager_websocketError, new rxjs_1.Subject(), "f");
41
+ __classPrivateFieldSet(this, _WebSocketConnectionManager_websocketSubscriptions, [], "f");
42
+ }
43
+ /**
44
+ * WebSocketクライアントの取得を行う
45
+ * WebSocketクライアントが存在しない場合は、本メソッド内で生成してから返す
46
+ * @returns 取得、生成結果
47
+ */
48
+ getOrCreate() {
49
+ return __awaiter(this, void 0, void 0, function* () {
50
+ if (__classPrivateFieldGet(this, _WebSocketConnectionManager_websocket, "f")) {
51
+ return __classPrivateFieldGet(this, _WebSocketConnectionManager_websocket, "f");
52
+ }
53
+ const websocket = yield (0, connect_ws_signal_1.connectWSSignal)(this.wsSignalUrl);
54
+ __classPrivateFieldSet(this, _WebSocketConnectionManager_websocketSubscriptions, [
55
+ (0, rxjs_1.fromEvent)(websocket, "error").subscribe(__classPrivateFieldGet(this, _WebSocketConnectionManager_websocketError, "f")),
56
+ (0, rxjs_1.fromEvent)(websocket, "close").subscribe(__classPrivateFieldGet(this, _WebSocketConnectionManager_websocketError, "f")),
57
+ ], "f");
58
+ __classPrivateFieldSet(this, _WebSocketConnectionManager_websocket, websocket, "f");
59
+ return websocket;
60
+ });
61
+ }
62
+ /**
63
+ * Websocketコネクションを切断する
64
+ * 本メソッドを呼び出すことで、WebSocketコネクションに関連するイベントストリームの購読も解除する
65
+ */
66
+ gracefulDisconnect() {
67
+ var _a;
68
+ (_a = __classPrivateFieldGet(this, _WebSocketConnectionManager_websocket, "f")) === null || _a === void 0 ? void 0 : _a.close();
69
+ __classPrivateFieldSet(this, _WebSocketConnectionManager_websocket, null, "f");
70
+ __classPrivateFieldGet(this, _WebSocketConnectionManager_websocketSubscriptions, "f").forEach((v) => {
71
+ v.unsubscribe();
72
+ });
73
+ __classPrivateFieldSet(this, _WebSocketConnectionManager_websocketSubscriptions, [], "f");
74
+ }
75
+ /**
76
+ * WebSocketのエラーを通知する
77
+ * @returns 通知ストリーム
78
+ */
79
+ errorNotifier() {
80
+ return __classPrivateFieldGet(this, _WebSocketConnectionManager_websocketError, "f");
81
+ }
82
+ }
83
+ exports.WebSocketConnectionManager = WebSocketConnectionManager;
84
+ _WebSocketConnectionManager_websocket = new WeakMap(), _WebSocketConnectionManager_websocketError = new WeakMap(), _WebSocketConnectionManager_websocketSubscriptions = new WeakMap();
@@ -0,0 +1,48 @@
1
+ import { ArmdozerId, Command, PilotId } from "gbraver-burst-core";
2
+ import { z } from "zod";
3
+ /** 選択したプレイヤーをホストに送信する */
4
+ export type SendPlayer = {
5
+ type: "send-player";
6
+ /** ゲームのフローID */
7
+ flowID: string;
8
+ /** 選択したアームドーザーのID */
9
+ armdozerId: ArmdozerId;
10
+ /** 選択したパイロットのID */
11
+ pilotId: PilotId;
12
+ };
13
+ /** SendPlayer zod のスキーマ */
14
+ export declare const SendPlayerSchema: z.ZodObject<{
15
+ type: z.ZodLiteral<"send-player">;
16
+ flowID: z.ZodString;
17
+ armdozerId: z.ZodString;
18
+ pilotId: z.ZodString;
19
+ }, z.core.$strip>;
20
+ /** コマンドをホストに送信する */
21
+ export type SendCommand = {
22
+ type: "send-command";
23
+ /** ゲームのフローID */
24
+ flowID: string;
25
+ /** コマンドの内容 */
26
+ command: Command;
27
+ };
28
+ /** SendCommand zod のスキーマ */
29
+ export declare const SendCommandSchema: z.ZodObject<{
30
+ type: z.ZodLiteral<"send-command">;
31
+ flowID: z.ZodString;
32
+ command: z.ZodUnion<readonly [z.ZodObject<{
33
+ type: z.ZodLiteral<"BATTERY_COMMAND">;
34
+ battery: z.ZodNumber;
35
+ }, z.core.$strip>, z.ZodObject<{
36
+ type: z.ZodLiteral<"BURST_COMMAND">;
37
+ }, z.core.$strip>, z.ZodObject<{
38
+ type: z.ZodLiteral<"PILOT_SKILL_COMMAND">;
39
+ }, z.core.$strip>]>;
40
+ }, z.core.$strip>;
41
+ /** ゲストから送信されるメッセージ */
42
+ export type GuestMessage = SendPlayer | SendCommand;
43
+ /**
44
+ * ゲストメッセージをホストに送信する
45
+ * @param dataChannel データチャンネル
46
+ * @param message メッセージ内容
47
+ */
48
+ export declare const sendGuestMessage: (dataChannel: RTCDataChannel, message: GuestMessage) => void;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sendGuestMessage = exports.SendCommandSchema = exports.SendPlayerSchema = void 0;
4
+ const gbraver_burst_core_1 = require("gbraver-burst-core");
5
+ const zod_1 = require("zod");
6
+ /** SendPlayer zod のスキーマ */
7
+ exports.SendPlayerSchema = zod_1.z.object({
8
+ type: zod_1.z.literal("send-player"),
9
+ flowID: zod_1.z.string(),
10
+ armdozerId: zod_1.z.string(),
11
+ pilotId: zod_1.z.string(),
12
+ });
13
+ /** SendCommand zod のスキーマ */
14
+ exports.SendCommandSchema = zod_1.z.object({
15
+ type: zod_1.z.literal("send-command"),
16
+ flowID: zod_1.z.string(),
17
+ command: gbraver_burst_core_1.CommandSchema,
18
+ });
19
+ /**
20
+ * ゲストメッセージをホストに送信する
21
+ * @param dataChannel データチャンネル
22
+ * @param message メッセージ内容
23
+ */
24
+ const sendGuestMessage = (dataChannel, message) => {
25
+ dataChannel.send(JSON.stringify(message));
26
+ };
27
+ exports.sendGuestMessage = sendGuestMessage;
@@ -0,0 +1,7 @@
1
+ import { BattleProgressed } from "../host/host-message";
2
+ /**
3
+ * ホストから「BattleProgressed」メッセージを待ち受ける
4
+ * @param dataChannel データチャネル
5
+ * @returns BattleProgressedメッセージの内容
6
+ */
7
+ export declare const receiveBattleProgressed: (dataChannel: RTCDataChannel) => Promise<BattleProgressed>;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.receiveBattleProgressed = void 0;
4
+ const parse_1 = require("../../json/parse");
5
+ const host_message_1 = require("../host/host-message");
6
+ /**
7
+ * ホストから「BattleProgressed」メッセージを待ち受ける
8
+ * @param dataChannel データチャネル
9
+ * @returns BattleProgressedメッセージの内容
10
+ */
11
+ const receiveBattleProgressed = (dataChannel) => {
12
+ let handler = null;
13
+ return new Promise((resolve) => {
14
+ handler = (event) => {
15
+ const data = (0, parse_1.parseJSON)(event.data);
16
+ const parsedBattleProgressed = host_message_1.BattleProgressedSchema.safeParse(data);
17
+ if (parsedBattleProgressed.success) {
18
+ resolve(parsedBattleProgressed.data);
19
+ return;
20
+ }
21
+ };
22
+ dataChannel.addEventListener("message", handler);
23
+ }).finally(() => {
24
+ if (handler) {
25
+ dataChannel.removeEventListener("message", handler);
26
+ }
27
+ });
28
+ };
29
+ exports.receiveBattleProgressed = receiveBattleProgressed;
@@ -0,0 +1,7 @@
1
+ import { BattleStart } from "../host/host-message";
2
+ /**
3
+ * ホストから「BattleStart」メッセージを待ち受ける
4
+ * @param dataChannel データチャネル
5
+ * @returns BattleStartメッセージの内容
6
+ */
7
+ export declare const receiveBattleStart: (dataChannel: RTCDataChannel) => Promise<BattleStart>;