homebridge-xbox-tv 2.9.11-beta.21 → 2.9.11-beta.3

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "displayName": "Xbox TV",
3
3
  "name": "homebridge-xbox-tv",
4
- "version": "2.9.11-beta.21",
4
+ "version": "2.9.11-beta.3",
5
5
  "description": "Homebridge plugin (https://github.com/homebridge/homebridge) to control Xbox game consoles.",
6
6
  "license": "MIT",
7
7
  "author": "grzegorz914",
@@ -12,9 +12,6 @@ class MESSAGE {
12
12
  //structure
13
13
  const structure = new Packets();
14
14
  this.structure = structure[type];
15
-
16
- //packet
17
- this.packet = new Packets(this.structure);
18
15
  };
19
16
 
20
17
  getMsgType(type) {
@@ -98,7 +95,7 @@ class MESSAGE {
98
95
  0x23: "titleLaunch",
99
96
  channelStartRequest: Buffer.from('a026', 'hex'),
100
97
  channelStartResponse: Buffer.from('a027', 'hex'),
101
- channelStop: Buffer.from('a028', 'hex'),
98
+ 0x28: "stopChannel",
102
99
  0x29: "system",
103
100
  disconnect: Buffer.from('802a', 'hex'),
104
101
  0x2E: "titleTouch",
@@ -195,15 +192,17 @@ class MESSAGE {
195
192
 
196
193
  // Lets decrypt the data when the payload is encrypted
197
194
  if (packet.payloadProtected) {
198
- const packetStructureProtected = this.packet[packet.type];
199
- const payloadDecrypted = crypto.decrypt(packet.payloadProtected, crypto.encrypt(data.slice(0, 16), crypto.getIv()));
200
- const packetDecrypted = new PacketStructure(payloadDecrypted);
195
+ let structureProtected = new Packets(this.structure);
196
+ structureProtected = structureProtected[packet.type];
197
+
198
+ let payloadDecrypted = crypto.decrypt(packet.payloadProtected, crypto.encrypt(data.slice(0, 16), crypto.getIv()));
199
+ payloadDecrypted = new PacketStructure(payloadDecrypted);
201
200
 
202
201
  packet.payloadDecrypted = new PacketStructure(payloadDecrypted).toBuffer();
203
202
  packet.payloadProtected = {};
204
203
 
205
- for (const name in packetStructureProtected) {
206
- packet.payloadProtected[name] = packetStructureProtected[name].unpack(packetDecrypted);
204
+ for (const name in structureProtected) {
205
+ packet.payloadProtected[name] = structureProtected[name].unpack(payloadDecrypted);
207
206
  };
208
207
  };
209
208
 
@@ -161,7 +161,7 @@ class PACKETS {
161
161
 
162
162
  const packets = {
163
163
  powerOn: {
164
- liveId: types.sgString(''),
164
+ liveId: types.sgString(),
165
165
  },
166
166
  json: {
167
167
  json: types.sgString('{}')
@@ -227,9 +227,6 @@ class PACKETS {
227
227
  channelTargetId: types.bytes(8, ''),
228
228
  result: types.uInt32('0'),
229
229
  },
230
- channelStop: {
231
- channelTargetId: types.bytes(8, ''),
232
- },
233
230
  acknowledge: {
234
231
  lowWatermark: types.uInt32('0'),
235
232
  processedList: types.sgList('processedList', []),
@@ -296,7 +293,7 @@ class PACKETS {
296
293
  command: types.uInt32('0'),
297
294
  },
298
295
  powerOff: {
299
- liveId: types.sgString(''),
296
+ liveId: types.sgString(),
300
297
  },
301
298
  disconnect: {
302
299
  reason: types.uInt32('1'),
@@ -12,8 +12,8 @@ class SIMPLE {
12
12
  this.structure = structure[type];
13
13
 
14
14
  //packet
15
- this.packet = new Packets(this.structure);
16
- this.structureProtected = this.structure.payloadProtected !== undefined ? this.packet[`${type}Protected`] : false;
15
+ const packet = new Packets(this.structure);
16
+ this.structureProtected = this.structure.payloadProtected !== undefined ? packet[`${type}Protected`] : false;
17
17
  };
18
18
 
19
19
  set(key, value, isProtected = false) {
@@ -89,6 +89,19 @@ class SIMPLE {
89
89
  case 'connectResponse':
90
90
  packet = this.pack1(Buffer.from('cc01', 'hex'), packetStructure.toBuffer(), '2');
91
91
  break;
92
+ case 'connectRequestProtected':
93
+ // Pad packet
94
+ if (packetStructure.toBuffer().length > 16) {
95
+ const padStart = packetStructure.toBuffer().length % 16;
96
+ const padTotal = (16 - padStart);
97
+ for (let paddingnum = (padStart + 1); paddingnum <= 16; paddingnum++) {
98
+ packetStructure.writeUInt8(padTotal);
99
+ };
100
+ };
101
+ let payloadEncrypted = crypto.encrypt(packetStructure.toBuffer(), crypto.getIv());
102
+ payloadEncrypted = new PacketStructure(payloadEncrypted)
103
+ packet = payloadEncrypted.toBuffer();
104
+ break;
92
105
  default:
93
106
  packet = packetStructure.toBuffer();
94
107
  };
@@ -153,13 +166,15 @@ class SIMPLE {
153
166
  packet.payloadProtected = packet.payloadProtected.slice(0, -32);
154
167
  packet.signature = packet.payloadProtected.slice(-32);
155
168
 
156
- const packetStructureProtected = this.packet[`${packet.type}Protected`];
157
- const payloadDecrypted = crypto.decrypt(packet.payloadProtected, packet.iv).slice(0, packet.payloadProtectedLength);
158
- const packetDecrypted = new PacketStructure(payloadDecrypted);
169
+ let payloadDecrypted = crypto.decrypt(packet.payloadProtected, packet.iv).slice(0, packet.payloadProtectedLength);
170
+ payloadDecrypted = new PacketStructure(payloadDecrypted);
171
+
172
+ let structureProtected = new Packets(this.structure);
173
+ structureProtected = structureProtected[`${packet.type}Protected`];
159
174
  packet.payloadProtected = {};
160
175
 
161
- for (const name in packetStructureProtected) {
162
- packet.payloadProtected[name] = packetStructureProtected[name].unpack(packetDecrypted);
176
+ for (const name in structureProtected) {
177
+ packet.payloadProtected[name] = structureProtected[name].unpack(payloadDecrypted);
163
178
  this.set('payloadProtected', packet.payloadProtected);
164
179
  }
165
180
  }
@@ -164,6 +164,17 @@ class STRUCTURE {
164
164
  return int32;
165
165
  };
166
166
 
167
+ readUInt64() {
168
+ let uint64 = 0;
169
+ try {
170
+ const rawData = this.readBytes(8);
171
+ uint64 = Buffer.from(rawData).readUIntBE(0, 8);
172
+ } catch (error) {
173
+ console.error(`Error reading unsigned 64-bit integer from packet: ${error}`);
174
+ }
175
+ return uint64;
176
+ };
177
+
167
178
  toBuffer() {
168
179
  return this.packet;
169
180
  };
@@ -29,7 +29,7 @@ class XBOXLOCALAPI extends EventEmitter {
29
29
  this.sequenceNumber = 1;
30
30
  this.targetParticipantId = 0;
31
31
  this.sourceParticipantId = 0;
32
- this.channelTargetId = 0;
32
+ this.channelServerId = 0;
33
33
  this.mediaRequestId = 0;
34
34
  this.emitDevInfo = true;
35
35
 
@@ -47,7 +47,7 @@ class XBOXLOCALAPI extends EventEmitter {
47
47
  const debug1 = this.debugLog ? this.emit('debug', `Received packet type hex: ${messageTypeHex}`) : false;
48
48
 
49
49
  //check message type exist in types
50
- const keysTypes = Object.keys(CONSTANTS.MessageTypes);
50
+ const keysTypes = Object.keys(CONSTANTS.MediaTypes);
51
51
  const keysTypesExist = keysTypes.includes(messageTypeHex);
52
52
 
53
53
  if (!keysTypesExist) {
@@ -255,10 +255,10 @@ class XBOXLOCALAPI extends EventEmitter {
255
255
  this.emit('stateChanged', power, volume, mute, mediaState, titleId, reference);
256
256
  const debug1 = this.debugLog ? this.emit('debug', `Status changed, app Id: ${titleId}, reference: ${reference}`) : false;
257
257
  };
258
- //this.emit('channelStartRequest');
259
258
 
260
259
  //start heart beat
261
260
  const sendHeartBeat = !this.heartBeatConnection ? this.emit('heartBeat') : false;
261
+ this.emit('channelStartRequest');
262
262
  }).on('channelStartRequest', async () => {
263
263
  const debug = this.debugLog ? this.emit('debug', 'Channel start request received.') : false;
264
264
 
@@ -273,8 +273,8 @@ class XBOXLOCALAPI extends EventEmitter {
273
273
 
274
274
  }).on('channelStartResponse', async (packet) => {
275
275
  const debug = this.debugLog ? this.emit('debug', 'Channel start response received.') : false;
276
- this.channelTargetId = packet.payloadProtected.result === 0 ? packet.payloadProtected.channelTargetId : 0;
277
- const debug1 = this.debugLog ? this.emit('debug', `Channel server id: ${this.channelTargetId}.`) : false;
276
+ this.channelServerId = packet.payloadProtected.result === 0 ? packet.payloadProtected.channelTargetId : 0;
277
+ const debug1 = this.debugLog ? this.emit('debug', `Channel server id: ${this.channelServerId}.`) : false;
278
278
  }).on('heartBeat', () => {
279
279
  if (this.heartBeatConnection) {
280
280
  return;
@@ -349,7 +349,7 @@ class XBOXLOCALAPI extends EventEmitter {
349
349
  const message = powerOn.pack(this.crypto);
350
350
  await this.sendSocketMessage(message);
351
351
 
352
- await new Promise(resolve => setTimeout(resolve, 1000));
352
+ await new Promise(resolve => setTimeout(resolve, 600));
353
353
  resolve();
354
354
  }
355
355
  this.emit('disconnected', 'Power On failed, please try again.');
@@ -418,7 +418,7 @@ class XBOXLOCALAPI extends EventEmitter {
418
418
  const gamepad = new MessagePacket('gamepad')
419
419
  gamepad.set('timestamp', Buffer.from(`000${timestampNow.toString()}`, 'hex'))
420
420
  gamepad.set('buttons', CONSTANTS.GamePadCommands[command]);
421
- gamepad.setChannel(this.channelTargetId);
421
+ gamepad.setChannel(this.channelServerId);
422
422
  const message = gamepad.pack(this.crypto, this.getSequenceNumber(), this.targetParticipantId, this.sourceParticipantId)
423
423
  await this.sendSocketMessage(message)
424
424
 
@@ -427,7 +427,7 @@ class XBOXLOCALAPI extends EventEmitter {
427
427
  const gamepadUnpress = MessagePacket('gamepad')
428
428
  gamepadUnpress.set('timestamp', Buffer.from(`000${timestamp.toString()}`, 'hex'))
429
429
  gamepadUnpress.set('buttons', 0);
430
- gamepadUnpress.setChannel(this.channelTargetId);
430
+ gamepadUnpress.setChannel(this.channelServerId);
431
431
  const message = gamepadUnpress.pack(this.crypto, this.getSequenceNumber(), this.targetParticipantId, this.sourceParticipantId);
432
432
  await this.sendSocketMessage(message);
433
433
  resolve();