-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathserver.js
292 lines (239 loc) · 9.47 KB
/
server.js
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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
const ConsoleWindow = require("node-hide-console-window");
ConsoleWindow.hideConsole();
setTimeout(() => {
var AutoLaunch = require('auto-launch');
const express = require("express");
const { Client } = require("openrgb-sdk");
const crypto = require('crypto');
const path = require("path");
const app = express();
let port = 9730; // Default port
let portMatch = false;
let consoleMode = false;
let fileName = path.basename(process.execPath);
if (fileName.includes("node.exe")) {
fileName = __filename.split("\\").pop().split("/").pop();
console.log("Starting js version server: ", fileName, "on port", port);
portMatch = fileName.match(/--port=\${(\d+)}/);
consoleMode = fileName.includes("--console");
} else {
console.log("Starting exe version server: ", fileName, "on port", port);
portMatch = fileName.match(/--port=\${(\d+)}/);
consoleMode = fileName.includes("--console");
noautostart = fileName.includes("--no-startup");
console.log(process.execPath)
var autoLauncher = new AutoLaunch({
name: 'OpenRGBBridge',
path: process.execPath,
});
if (!noautostart) {
autoLauncher.enable();
autoLauncher.isEnabled()
.then(function (isEnabled) {
if (isEnabled) {
return;
}
autoLauncher.enable();
})
.catch(function (err) {
console.error(err);
});
}
else {
autoLauncher.disable();
}
}
if (consoleMode) {
ConsoleWindow.showConsole();
console.log("Console mode enabled");
}
if (portMatch) {
const newPort = parseInt(portMatch[1], 10);
console.log("Port number detected in the file name:", newPort);
port = newPort;
}
let client;
let hostSDK;
let portSDK;
//create an array of the id and the hash of the device
let deviceHashesWithId = [];
app.use(express.json());
app.get("/connect", async (req, res) => {
try {
const { host, port } = req.query;
//make the host and port global so we can use it in the other functions and reconnect if the connection is lost
if (!host || !port) {
return res.status(400).send("Both host and port parameters are required.");
}
console.log("Connecting to", host, "on port", port + "and the client ask for the device list:");
if (client) {
await client.disconnect();
client = undefined;
console.log("Disconnected successfully");
}
hostSDK = host;
portSDK = port;
client = new Client("OpenRGBBridge", parseInt(port), host);
await client.connect();
const controllerCount = await client.getControllerCount();
let deviceList = [];
deviceHashesWithId = [];
for (let deviceId = 0; deviceId < controllerCount; deviceId++) {
//for each device edit the device id to be a hash of the string combining the device name,vendor,description,version,serial and location
//this will be used to identify the device in the frontend because the device id can change if the device is disconnected and reconnected and the device id given by the sdk is not unique to the device it"s just the order in which the device was connected
const deviceData = await client.getControllerData(deviceId);
let deviceOldId = deviceData.deviceId;
// Combine device properties into a string
const deviceInfoString = `${deviceData.deviceId}${deviceData.name}${deviceData.vendor}${deviceData.description}${deviceData.version}${deviceData.serial}${deviceData.location}`;
console.log("Device Info String:", deviceInfoString);
// Create a hash of the combined string
const hash = crypto.createHash('md5').update(deviceInfoString).digest('hex');
console.log("Device Info Hash:", hash);
// Add the hash to the device data
deviceData.deviceId = hash;
let deviceNewId = deviceData.deviceId;
// Push the modified device data to the list
deviceList.push(deviceData);
let deviceArray = [deviceOldId, deviceNewId];
deviceHashesWithId.push(deviceArray);
}
console.log("Device list Retrived Sucessfully. There are", deviceList.length, "devices available");
res.status(200).json(deviceList);
return;
} catch (error) {
console.error("Error connecting:", error);
res.status(500).send("Internal Server Error");
}
});
app.get("/disconnect", async (req, res) => {
try {
await client.disconnect();
client = undefined;
res.status(200).send("Disconnected successfully");
console.log("Disconnected successfully");
} catch (error) {
console.error("Error disconnecting:", error);
res.status(500).send("Internal Server Error");
}
});
app.get("/GetAvalaibleDevices", async (req, res) => {
try {
const controllerCount = await client.getControllerCount();
let deviceList = [];
deviceHashesWithId = [];
for (let deviceId = 0; deviceId < controllerCount; deviceId++) {
deviceList.push(await client.getControllerData(deviceId));
}
res.status(200).json(deviceList);
console.log("Device list Retrived Sucessfully. There are", deviceList.length, "devices available");
} catch (error) {
console.error("Error getting device list:", error);
res.status(500).send("Internal Server Error");
}
});
app.get("/setColors", async (req, res) => {
try {
let { colors, deviceId } = req.query;
colors = JSON.parse(colors);
//console.log("Changing colors of device", deviceId, "to", colors);
if (!colors || !deviceId) {
return res.status(400).send("Both colors and deviceId parameters are required.");
}
const controllerCount = await client.getControllerCount();
//match the hash to the device id and set the mode of the old device id and not the new one
for (let i = 0; i < deviceHashesWithId.length; i++) {
if (deviceHashesWithId[i][1] === deviceId) {
deviceId = deviceHashesWithId[i][0];
break;
}
}
if (deviceId < 0 || deviceId >= controllerCount) {
return res.status(400).send("Invalid deviceId.");
}
await client.updateLeds(deviceId, colors);
res.status(200).send("Colors updated successfully");
//console.log("Colors updated successfully");
} catch (error) {
console.error("Error setting colors:", error);
res.status(500).send("Internal Server Error");
//try to reconnect
//make this a try catch block so we don't get an unhandled promise rejection
try {
if (client) {
await client.disconnect();
client = undefined;
console.log("Disconnected successfully");
}
//try to reconnect using the last known host and port
client = new Client("OpenRGBBridge", parseInt(portSDK), hostSDK);
await client.connect();
} catch (error) {
console.error("Error reconnecting:", error);
}
}
});
app.get("/setMode", async (req, res) => {
try {
let { mode, deviceId } = req.query;
mode = parseInt(mode);
console.log("Changing mode of device", deviceId, "to", mode);
if (!mode || !deviceId) {
return res.status(400).send("Both mode and deviceId parameters are required.");
}
const controllerCount = await client.getControllerCount();
//match the hash to the device id and set the mode of the old device id and not the new one
for (let i = 0; i < deviceHashesWithId.length; i++) {
if (deviceHashesWithId[i][1] === deviceId) {
deviceId = deviceHashesWithId[i][0];
break;
}
}
if (deviceId < 0 || deviceId >= controllerCount) {
return res.status(400).send("Invalid deviceId.");
}
await client.updateMode(deviceId, mode);
res.status(200).send("Mode updated successfully");
console.log("Mode updated successfully");
} catch (error) {
console.error("Error setting mode:", error);
res.status(500).send("Internal Server Error");
}
});
app.listen(port, () => {
console.log(`Server is running at http://localhost:${port}`);
});
process.on('SIGINT', async () => {
console.log('Received SIGINT signal. Disconnecting from the server...');
await disconnectAndExit();
});
if (process.platform === 'win32') {
const rl = require('readline').createInterface({
input: process.stdin,
output: process.stdout
});
rl.on('SIGINT', () => {
process.emit('SIGINT');
});
}
process.on('SIGTERM', async () => {
console.log('Received SIGTERM signal. Disconnecting from the server...');
await disconnectAndExit();
});
async function disconnectAndExit() {
try {
if (client) {
//wait 10 seconds for the client to disconnect
await client.disconnect();
client = undefined;
console.log('Disconnected successfully');
}
server.close(() => {
console.log('Server closed. Exiting...');
process.exit(0);
});
} catch (error) {
console.error('Error disconnecting:', error);
process.exit(1);
}
}
}, 5000);