@4players/odin-common 4.0.0 → 4.0.2
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/mod.d.ts +26 -4431
- package/package.json +1 -1
- package/plugin/api.d.ts +159 -0
- package/rpc/commands.d.ts +253 -0
- package/rpc/notifications.d.ts +1626 -0
- package/schema/channels.d.ts +11 -0
- package/schema/media.d.ts +122 -0
- package/schema/message.d.ts +12 -0
- package/schema/peer.d.ts +226 -0
- package/schema/room.d.ts +1673 -0
- package/schema/serialization.d.ts +12 -0
- package/schema/token.d.ts +58 -0
- package/schema/webrtc.d.ts +42 -0
- package/utility/base64.d.ts +3 -0
- package/utility/bytearray.d.ts +4 -0
- package/utility/codec.d.ts +15 -0
- package/utility/environment.d.ts +6 -0
- package/utility/iterable.d.ts +1 -0
- package/utility/json.d.ts +2 -0
- package/utility/log.d.ts +79 -0
- package/utility/result.d.ts +18 -0
- package/utility/selector.d.ts +7 -0
- package/utility/sleep.d.ts +4 -0
- package/utility/strand.d.ts +8 -0
- package/utility/url.d.ts +3 -0
- package/utility/uuid.d.ts +2 -0
- package/utility/validation.d.ts +10 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@4players/odin-common",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.2",
|
|
4
4
|
"description": "A collection of commonly used type definitions and utility functions across ODIN web projects",
|
|
5
5
|
"author": "Josho Bleicker <josho.bleicker@4players.io> (https://www.4players.io)",
|
|
6
6
|
"homepage": "https://www.4players.io",
|
package/plugin/api.d.ts
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
export declare const MinDBFS = -758.596;
|
|
2
|
+
export declare namespace Backend {
|
|
3
|
+
type UID = string;
|
|
4
|
+
type OnStatusChanged = (status: "started" | "stopped") => void;
|
|
5
|
+
type OnEvent = (method: string, properties: unknown) => void;
|
|
6
|
+
type Version = "5";
|
|
7
|
+
enum Transport {
|
|
8
|
+
H3 = "h3",
|
|
9
|
+
WebRTC = "webrtc"
|
|
10
|
+
}
|
|
11
|
+
interface Plugin {
|
|
12
|
+
readonly version: Version;
|
|
13
|
+
readonly playbackVolume: PlaybackVolume;
|
|
14
|
+
readonly supportedTransports: (Transport.WebRTC | Transport.H3)[];
|
|
15
|
+
joinRoom(parameters: JoinRoomParameters): Room;
|
|
16
|
+
createAudioPlayback(parameters: CreateAudioPlaybackParameters): Promise<AudioPlayback>;
|
|
17
|
+
createAudioCapture(parameters: CreateAudioCaptureParameters): Promise<AudioCapture>;
|
|
18
|
+
createVideoCapture(ms: MediaStream, options?: VideoInputOptions): Promise<VideoCapture>;
|
|
19
|
+
createVideoPlayback(parameters: CreateVideoPlaybackParameters): Promise<VideoPlayback>;
|
|
20
|
+
enumerateDevices(): Promise<Array<Device>>;
|
|
21
|
+
setOutputVolume(volume: PlaybackVolume): void;
|
|
22
|
+
setOutputDevice(device: DeviceParameters): Promise<void>;
|
|
23
|
+
close(): void;
|
|
24
|
+
}
|
|
25
|
+
interface Device {
|
|
26
|
+
readonly type: "AudioPlayback" | "AudioCapture";
|
|
27
|
+
readonly name: string;
|
|
28
|
+
readonly id: string;
|
|
29
|
+
readonly isDefault: boolean;
|
|
30
|
+
}
|
|
31
|
+
interface DeviceParameters {
|
|
32
|
+
readonly device?: Device;
|
|
33
|
+
onStatusChanged?: OnStatusChanged;
|
|
34
|
+
}
|
|
35
|
+
interface Activity {
|
|
36
|
+
isSilent: boolean;
|
|
37
|
+
rmsDBFS: number;
|
|
38
|
+
}
|
|
39
|
+
interface JitterStats {
|
|
40
|
+
packetsSeen: number;
|
|
41
|
+
packetsProcessed: number;
|
|
42
|
+
packetsTooEarly: number;
|
|
43
|
+
packetsTooLate: number;
|
|
44
|
+
packetsDropped: number;
|
|
45
|
+
packetsInvalid: number;
|
|
46
|
+
packetsRepeated: number;
|
|
47
|
+
packetsLost: number;
|
|
48
|
+
}
|
|
49
|
+
interface ConnectionStats {
|
|
50
|
+
bytesSent: number;
|
|
51
|
+
bytesReceived: number;
|
|
52
|
+
packetsSent: number;
|
|
53
|
+
packetsReceived: number;
|
|
54
|
+
rtt: number;
|
|
55
|
+
}
|
|
56
|
+
interface JoinRoomParameters {
|
|
57
|
+
readonly gateway: string | undefined;
|
|
58
|
+
readonly token: string;
|
|
59
|
+
readonly roomId?: string;
|
|
60
|
+
readonly userData?: Uint8Array;
|
|
61
|
+
readonly position?: [number, number, number];
|
|
62
|
+
readonly cipher?: SetupCipherSettings;
|
|
63
|
+
readonly onEvent: OnEvent;
|
|
64
|
+
readonly transport?: Transport;
|
|
65
|
+
}
|
|
66
|
+
interface Room {
|
|
67
|
+
readonly token: string;
|
|
68
|
+
readonly cipher: Cipher | undefined;
|
|
69
|
+
connectionStats: ConnectionStats;
|
|
70
|
+
request(method: string, properties: unknown): Promise<unknown>;
|
|
71
|
+
link(media: Media): Promise<void>;
|
|
72
|
+
unlink(media: Media): void;
|
|
73
|
+
close(): void;
|
|
74
|
+
}
|
|
75
|
+
interface Media {
|
|
76
|
+
readonly customType?: string;
|
|
77
|
+
close(): void;
|
|
78
|
+
}
|
|
79
|
+
interface AudioMedia extends Media {
|
|
80
|
+
readonly activity: Activity;
|
|
81
|
+
}
|
|
82
|
+
interface CreateAudioPlaybackParameters {
|
|
83
|
+
readonly uid: UID;
|
|
84
|
+
readonly volume?: PlaybackVolume;
|
|
85
|
+
readonly customType?: string;
|
|
86
|
+
}
|
|
87
|
+
interface CreateVideoPlaybackParameters {
|
|
88
|
+
readonly uid: UID;
|
|
89
|
+
readonly customType?: string;
|
|
90
|
+
}
|
|
91
|
+
interface AudioPlayback extends AudioMedia {
|
|
92
|
+
readonly volume: PlaybackVolume;
|
|
93
|
+
readonly uid: UID;
|
|
94
|
+
jitterStats: JitterStats;
|
|
95
|
+
setVolume(value: PlaybackVolume): Promise<void>;
|
|
96
|
+
}
|
|
97
|
+
interface CreateAudioCaptureParameters extends Partial<DeviceParameters> {
|
|
98
|
+
readonly volume?: CaptureVolume;
|
|
99
|
+
readonly vad?: VadConfig;
|
|
100
|
+
readonly apm?: ApmConfig;
|
|
101
|
+
}
|
|
102
|
+
interface AudioCapture extends AudioMedia {
|
|
103
|
+
readonly volume: CaptureVolume;
|
|
104
|
+
readonly vad?: VadConfig;
|
|
105
|
+
readonly apm?: ApmConfig;
|
|
106
|
+
setVad(config: VadConfig): void;
|
|
107
|
+
setApm(config: ApmConfig): Promise<void>;
|
|
108
|
+
setDevice(device: DeviceParameters): Promise<void>;
|
|
109
|
+
setVolume(value: CaptureVolume): Promise<void>;
|
|
110
|
+
}
|
|
111
|
+
interface VideoCapture extends Media {
|
|
112
|
+
mediaStream?: MediaStream;
|
|
113
|
+
setDevice(ms: MediaStream): Promise<void>;
|
|
114
|
+
}
|
|
115
|
+
interface VideoPlayback extends Media {
|
|
116
|
+
readonly mediaStream?: MediaStream;
|
|
117
|
+
readonly uid: UID;
|
|
118
|
+
}
|
|
119
|
+
type PlaybackVolume = [number, number];
|
|
120
|
+
type CaptureVolume = "muted" | number;
|
|
121
|
+
interface VadConfig {
|
|
122
|
+
voiceActivity?: SensitivityRange;
|
|
123
|
+
volumeGate?: SensitivityRange;
|
|
124
|
+
}
|
|
125
|
+
interface SensitivityRange {
|
|
126
|
+
attackThreshold: number;
|
|
127
|
+
releaseThreshold: number;
|
|
128
|
+
}
|
|
129
|
+
interface ApmConfig {
|
|
130
|
+
echoCanceller: boolean;
|
|
131
|
+
highPassFilter: boolean;
|
|
132
|
+
preAmplifier: boolean;
|
|
133
|
+
captureLevelAdjustment: boolean;
|
|
134
|
+
noiseSuppression: "None" | "Low" | "Moderate" | "High" | "VeryHigh";
|
|
135
|
+
transientSuppressor: boolean;
|
|
136
|
+
gainController: boolean;
|
|
137
|
+
}
|
|
138
|
+
type SetupCipherSettings = {
|
|
139
|
+
type: "OdinCrypto";
|
|
140
|
+
} & OdinCryptoSettings;
|
|
141
|
+
type CipherSettings = OdinCryptoSettings;
|
|
142
|
+
interface OdinCryptoSettings {
|
|
143
|
+
password: string | null;
|
|
144
|
+
}
|
|
145
|
+
enum PeerCipherStatus {
|
|
146
|
+
InvalidPassword = -1,
|
|
147
|
+
Unknown = 0,
|
|
148
|
+
Unencrypted = 1,
|
|
149
|
+
Encrypted = 2
|
|
150
|
+
}
|
|
151
|
+
interface Cipher {
|
|
152
|
+
configure(settings: CipherSettings): void;
|
|
153
|
+
getPeerStatus(peerId: number): PeerCipherStatus;
|
|
154
|
+
}
|
|
155
|
+
type VideoInputOptions = {
|
|
156
|
+
codec?: "H264" | "VP8" | "VP9";
|
|
157
|
+
customType?: string;
|
|
158
|
+
};
|
|
159
|
+
}
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
import { type infer, z } from "zod";
|
|
2
|
+
export type { infer as Infer };
|
|
3
|
+
export type Commands = Record<string, {
|
|
4
|
+
request: z.ZodTypeAny;
|
|
5
|
+
response: z.ZodTypeAny;
|
|
6
|
+
}>;
|
|
7
|
+
export declare const MainCommandsRpc: {
|
|
8
|
+
Hello: {
|
|
9
|
+
request: z.ZodObject<{
|
|
10
|
+
stream: z.ZodLiteral<"main">;
|
|
11
|
+
}, "strip", z.ZodTypeAny, {
|
|
12
|
+
stream?: "main";
|
|
13
|
+
}, {
|
|
14
|
+
stream?: "main";
|
|
15
|
+
}>;
|
|
16
|
+
response: z.ZodNull;
|
|
17
|
+
};
|
|
18
|
+
JoinRoom: {
|
|
19
|
+
request: z.ZodObject<{
|
|
20
|
+
token: z.ZodString;
|
|
21
|
+
room_id: z.ZodString;
|
|
22
|
+
user_data: z.ZodType<Uint8Array, z.ZodTypeDef, Uint8Array>;
|
|
23
|
+
position: z.ZodUnion<[z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>, z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>]>;
|
|
24
|
+
}, "strip", z.ZodTypeAny, {
|
|
25
|
+
position?: [number, number, number, ...unknown[]] | [number, number, ...unknown[]];
|
|
26
|
+
user_data?: Uint8Array;
|
|
27
|
+
room_id?: string;
|
|
28
|
+
token?: string;
|
|
29
|
+
}, {
|
|
30
|
+
position?: [number, number, number, ...unknown[]] | [number, number, ...unknown[]];
|
|
31
|
+
user_data?: Uint8Array;
|
|
32
|
+
room_id?: string;
|
|
33
|
+
token?: string;
|
|
34
|
+
}>;
|
|
35
|
+
response: z.ZodObject<{
|
|
36
|
+
peer_id: z.ZodNumber;
|
|
37
|
+
stream_id: z.ZodOptional<z.ZodNumber>;
|
|
38
|
+
token: z.ZodOptional<z.ZodString>;
|
|
39
|
+
}, "strip", z.ZodTypeAny, {
|
|
40
|
+
peer_id?: number;
|
|
41
|
+
token?: string;
|
|
42
|
+
stream_id?: number;
|
|
43
|
+
}, {
|
|
44
|
+
peer_id?: number;
|
|
45
|
+
token?: string;
|
|
46
|
+
stream_id?: number;
|
|
47
|
+
}>;
|
|
48
|
+
};
|
|
49
|
+
WebRtcUpdate: {
|
|
50
|
+
request: z.ZodDiscriminatedUnion<"kind", [z.ZodObject<{
|
|
51
|
+
kind: z.ZodLiteral<"Sdp">;
|
|
52
|
+
type: z.ZodEnum<["Answer", "Offer"]>;
|
|
53
|
+
sdp: z.ZodString;
|
|
54
|
+
media_map: z.ZodArray<z.ZodTuple<[z.ZodNumber, z.ZodString], null>, "many">;
|
|
55
|
+
}, "strip", z.ZodTypeAny, {
|
|
56
|
+
type?: "Answer" | "Offer";
|
|
57
|
+
kind?: "Sdp";
|
|
58
|
+
sdp?: string;
|
|
59
|
+
media_map?: [number, string, ...unknown[]][];
|
|
60
|
+
}, {
|
|
61
|
+
type?: "Answer" | "Offer";
|
|
62
|
+
kind?: "Sdp";
|
|
63
|
+
sdp?: string;
|
|
64
|
+
media_map?: [number, string, ...unknown[]][];
|
|
65
|
+
}>, z.ZodObject<{
|
|
66
|
+
kind: z.ZodLiteral<"Trickle">;
|
|
67
|
+
candidate: z.ZodString;
|
|
68
|
+
spd_mid: z.ZodOptional<z.ZodString>;
|
|
69
|
+
spd_mline_index: z.ZodOptional<z.ZodNumber>;
|
|
70
|
+
username_fragment: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNull]>>;
|
|
71
|
+
}, "strip", z.ZodTypeAny, {
|
|
72
|
+
candidate?: string;
|
|
73
|
+
kind?: "Trickle";
|
|
74
|
+
spd_mid?: string;
|
|
75
|
+
spd_mline_index?: number;
|
|
76
|
+
username_fragment?: string;
|
|
77
|
+
}, {
|
|
78
|
+
candidate?: string;
|
|
79
|
+
kind?: "Trickle";
|
|
80
|
+
spd_mid?: string;
|
|
81
|
+
spd_mline_index?: number;
|
|
82
|
+
username_fragment?: string;
|
|
83
|
+
}>, z.ZodObject<{
|
|
84
|
+
kind: z.ZodLiteral<"TrickleFinished">;
|
|
85
|
+
}, "strip", z.ZodTypeAny, {
|
|
86
|
+
kind?: "TrickleFinished";
|
|
87
|
+
}, {
|
|
88
|
+
kind?: "TrickleFinished";
|
|
89
|
+
}>]>;
|
|
90
|
+
response: z.ZodNull;
|
|
91
|
+
};
|
|
92
|
+
RequestReconnectToken: {
|
|
93
|
+
request: z.ZodObject<{
|
|
94
|
+
peer_id: z.ZodOptional<z.ZodNumber>;
|
|
95
|
+
}, "strip", z.ZodTypeAny, {
|
|
96
|
+
peer_id?: number;
|
|
97
|
+
}, {
|
|
98
|
+
peer_id?: number;
|
|
99
|
+
}>;
|
|
100
|
+
response: z.ZodString;
|
|
101
|
+
};
|
|
102
|
+
Ping: {
|
|
103
|
+
request: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
|
|
104
|
+
response: z.ZodNull;
|
|
105
|
+
};
|
|
106
|
+
};
|
|
107
|
+
export type MainCommands = typeof MainCommandsRpc;
|
|
108
|
+
export declare const RoomCommandsRpc: {
|
|
109
|
+
Hello: {
|
|
110
|
+
request: z.ZodObject<{
|
|
111
|
+
stream: z.ZodLiteral<"room">;
|
|
112
|
+
token: z.ZodString;
|
|
113
|
+
room_id: z.ZodString;
|
|
114
|
+
user_data: z.ZodType<Uint8Array, z.ZodTypeDef, Uint8Array>;
|
|
115
|
+
position: z.ZodUnion<[z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>, z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>]>;
|
|
116
|
+
}, "strip", z.ZodTypeAny, {
|
|
117
|
+
stream?: "room";
|
|
118
|
+
position?: [number, number, number, ...unknown[]] | [number, number, ...unknown[]];
|
|
119
|
+
user_data?: Uint8Array;
|
|
120
|
+
room_id?: string;
|
|
121
|
+
token?: string;
|
|
122
|
+
}, {
|
|
123
|
+
stream?: "room";
|
|
124
|
+
position?: [number, number, number, ...unknown[]] | [number, number, ...unknown[]];
|
|
125
|
+
user_data?: Uint8Array;
|
|
126
|
+
room_id?: string;
|
|
127
|
+
token?: string;
|
|
128
|
+
}>;
|
|
129
|
+
response: z.ZodNull;
|
|
130
|
+
};
|
|
131
|
+
UpdatePeer: {
|
|
132
|
+
request: z.ZodObject<{
|
|
133
|
+
user_data: z.ZodType<Uint8Array, z.ZodTypeDef, Uint8Array>;
|
|
134
|
+
}, "strip", z.ZodTypeAny, {
|
|
135
|
+
user_data?: Uint8Array;
|
|
136
|
+
}, {
|
|
137
|
+
user_data?: Uint8Array;
|
|
138
|
+
}>;
|
|
139
|
+
response: z.ZodNull;
|
|
140
|
+
};
|
|
141
|
+
StartMedia: {
|
|
142
|
+
request: z.ZodObject<{
|
|
143
|
+
media_id: z.ZodNumber;
|
|
144
|
+
properties: z.ZodUnion<[z.ZodObject<{
|
|
145
|
+
kind: z.ZodOptional<z.ZodLiteral<"audio">>;
|
|
146
|
+
uid: z.ZodOptional<z.ZodString>;
|
|
147
|
+
customType: z.ZodOptional<z.ZodString>;
|
|
148
|
+
}, "strip", z.ZodTypeAny, {
|
|
149
|
+
uid?: string;
|
|
150
|
+
kind?: "audio";
|
|
151
|
+
customType?: string;
|
|
152
|
+
}, {
|
|
153
|
+
uid?: string;
|
|
154
|
+
kind?: "audio";
|
|
155
|
+
customType?: string;
|
|
156
|
+
}>, z.ZodObject<{
|
|
157
|
+
kind: z.ZodOptional<z.ZodLiteral<"video">>;
|
|
158
|
+
codec: z.ZodOptional<z.ZodString>;
|
|
159
|
+
uid: z.ZodOptional<z.ZodString>;
|
|
160
|
+
customType: z.ZodOptional<z.ZodString>;
|
|
161
|
+
}, "strip", z.ZodTypeAny, {
|
|
162
|
+
codec?: string;
|
|
163
|
+
uid?: string;
|
|
164
|
+
kind?: "video";
|
|
165
|
+
customType?: string;
|
|
166
|
+
}, {
|
|
167
|
+
codec?: string;
|
|
168
|
+
uid?: string;
|
|
169
|
+
kind?: "video";
|
|
170
|
+
customType?: string;
|
|
171
|
+
}>]>;
|
|
172
|
+
}, "strip", z.ZodTypeAny, {
|
|
173
|
+
properties?: {
|
|
174
|
+
uid?: string;
|
|
175
|
+
kind?: "audio";
|
|
176
|
+
customType?: string;
|
|
177
|
+
} | {
|
|
178
|
+
codec?: string;
|
|
179
|
+
uid?: string;
|
|
180
|
+
kind?: "video";
|
|
181
|
+
customType?: string;
|
|
182
|
+
};
|
|
183
|
+
media_id?: number;
|
|
184
|
+
}, {
|
|
185
|
+
properties?: {
|
|
186
|
+
uid?: string;
|
|
187
|
+
kind?: "audio";
|
|
188
|
+
customType?: string;
|
|
189
|
+
} | {
|
|
190
|
+
codec?: string;
|
|
191
|
+
uid?: string;
|
|
192
|
+
kind?: "video";
|
|
193
|
+
customType?: string;
|
|
194
|
+
};
|
|
195
|
+
media_id?: number;
|
|
196
|
+
}>;
|
|
197
|
+
response: z.ZodNull;
|
|
198
|
+
};
|
|
199
|
+
StopMedia: {
|
|
200
|
+
request: z.ZodObject<{
|
|
201
|
+
media_id: z.ZodNumber;
|
|
202
|
+
}, "strip", z.ZodTypeAny, {
|
|
203
|
+
media_id?: number;
|
|
204
|
+
}, {
|
|
205
|
+
media_id?: number;
|
|
206
|
+
}>;
|
|
207
|
+
response: z.ZodNull;
|
|
208
|
+
};
|
|
209
|
+
PauseMedia: {
|
|
210
|
+
request: z.ZodObject<{
|
|
211
|
+
media_id: z.ZodNumber;
|
|
212
|
+
}, "strip", z.ZodTypeAny, {
|
|
213
|
+
media_id?: number;
|
|
214
|
+
}, {
|
|
215
|
+
media_id?: number;
|
|
216
|
+
}>;
|
|
217
|
+
response: z.ZodNull;
|
|
218
|
+
};
|
|
219
|
+
ResumeMedia: {
|
|
220
|
+
request: z.ZodObject<{
|
|
221
|
+
media_id: z.ZodNumber;
|
|
222
|
+
}, "strip", z.ZodTypeAny, {
|
|
223
|
+
media_id?: number;
|
|
224
|
+
}, {
|
|
225
|
+
media_id?: number;
|
|
226
|
+
}>;
|
|
227
|
+
response: z.ZodNull;
|
|
228
|
+
};
|
|
229
|
+
SetPeerPosition: {
|
|
230
|
+
request: z.ZodObject<{
|
|
231
|
+
position: z.ZodUnion<[z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>, z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>]>;
|
|
232
|
+
}, "strip", z.ZodTypeAny, {
|
|
233
|
+
position?: [number, number, number, ...unknown[]] | [number, number, ...unknown[]];
|
|
234
|
+
}, {
|
|
235
|
+
position?: [number, number, number, ...unknown[]] | [number, number, ...unknown[]];
|
|
236
|
+
}>;
|
|
237
|
+
response: z.ZodNull;
|
|
238
|
+
};
|
|
239
|
+
SendMessage: {
|
|
240
|
+
request: z.ZodObject<{
|
|
241
|
+
target_peer_ids: z.ZodOptional<z.ZodArray<z.ZodNumber, "many">>;
|
|
242
|
+
message: z.ZodType<Uint8Array, z.ZodTypeDef, Uint8Array>;
|
|
243
|
+
}, "strip", z.ZodTypeAny, {
|
|
244
|
+
message?: Uint8Array;
|
|
245
|
+
target_peer_ids?: number[];
|
|
246
|
+
}, {
|
|
247
|
+
message?: Uint8Array;
|
|
248
|
+
target_peer_ids?: number[];
|
|
249
|
+
}>;
|
|
250
|
+
response: z.ZodNull;
|
|
251
|
+
};
|
|
252
|
+
};
|
|
253
|
+
export type RoomCommands = typeof RoomCommandsRpc;
|