forked from mixer/interactive-node
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgroups.ts
176 lines (145 loc) · 4.97 KB
/
groups.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
/* tslint:disable:no-console */
import * as WebSocket from 'ws';
import {
GameClient,
Group,
IParticipant,
ISceneDataArray,
setWebSocket,
} from '../lib';
import { makeControls } from './util';
if (process.argv.length < 4) {
console.log('Usage gameClient.exe <token> <versionId>');
console.log(process.argv);
process.exit();
}
// We need to tell the interactive client what type of websocket we are using.
setWebSocket(WebSocket);
// As we're on the Streamer's side we need a "GameClient" instance
const client = new GameClient();
// Log when we're connected to interactive and setup your game!
client.on('open', () => {
console.log('Connected to Interactive!');
// Pull the scenes and groups from the interactive server
client
.synchronizeState()
// Set the client as ready so that interactive controls show up
.then(() => client.ready(true))
// Create the scenes for our application
.then(createScenes)
// Create the groups for our application
.then(createGroups)
// Catch any errors
.catch((reason: Error) => console.error('Promise rejected', reason));
});
// A collection of interval timers, one for each participant
const participantTimers: Map<string, number> = new Map<string, number>();
// The time between when we switch groups for each participant
const delayTime = 2000;
// These can be un-commented to see the raw JSON messages under the hood
// client.on('message', (err: any) => console.log('<<<', err));
// client.on('send', (err: any) => console.log('>>>', err));
// client.on('error', (err: any) => console.log(err));
/**
* Swaps the group the current participant is in between secondGroup and default.
*/
function swapParticipantGroup(participant: IParticipant): Promise<void> {
if (participant.groupID === 'default') {
participant.groupID = 'secondGroup';
} else {
participant.groupID = 'default';
}
return client.updateParticipants({
participants: [participant],
});
}
/**
* Removes the participant info from the participantTimers map and stops their timer.
*/
function removeParticipant(participantSessionId: string): void {
if (participantTimers.has(participantSessionId)) {
clearInterval(participantTimers[participantSessionId]);
delete participantTimers[participantSessionId];
}
}
/**
* Create the scenes used by the application.
*/
function createScenes(): Promise<ISceneDataArray> {
const defaultScene = client.state.getScene('default');
defaultScene.createControls(makeControls(1, () => 'Scene: default'));
const secondScene = {
sceneID: 'secondScene',
controls: makeControls(1, () => 'Scene: second'),
};
return client.createScenes({
scenes: [secondScene],
});
}
/**
* Create and setup the groups used by the application.
*/
function createGroups(): Promise<void> {
const defaultGroup = client.state.getGroup('default');
defaultGroup.sceneID = 'default';
const secondGroup = new Group({
groupID: 'secondGroup',
sceneID: 'secondScene',
});
const thirdGroup = new Group({
groupID: 'thirdGroup',
sceneID: 'default',
});
return (
client
// First update the default group
.updateGroups({
groups: [defaultGroup],
})
// Then create the new groups
.then(() =>
client.createGroups({
groups: [secondGroup, thirdGroup],
}),
)
// Then delete the third group
.then(() =>
client.deleteGroup({
groupID: thirdGroup.groupID,
reassignGroupID: defaultGroup.groupID,
}),
)
);
}
// Now we open the connection passing in our authentication details and an experienceId.
client
// Open the Mixer interactive client with command line args
.open({
authToken: process.argv[2],
versionId: parseInt(process.argv[3], 10),
})
// Catch any errors
.catch((reason: Error) => console.error('Promise rejected', reason));
client.state.on('participantJoin', (participant: IParticipant) => {
console.log(`${participant.username}(${participant.sessionID}) Joined`);
if (!participantTimers.has(participant.sessionID)) {
participantTimers[participant.sessionID] = setInterval(() => {
const p = client.state.getParticipantBySessionID(
participant.sessionID,
);
if (p) {
swapParticipantGroup(p);
} else {
removeParticipant(participant.sessionID);
}
}, delayTime);
}
});
client.state.on(
'participantLeave',
(participantSessionID: string, participant: IParticipant) => {
console.log(`${participant.username}(${participantSessionID}) Left`);
removeParticipant(participantSessionID);
},
);
/* tslint:enable:no-console */