-
Notifications
You must be signed in to change notification settings - Fork 21
/
ZwiftPacketMonitor.js
78 lines (71 loc) · 2.75 KB
/
ZwiftPacketMonitor.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
const EventEmitter = require('events')
const Cap = require('cap').Cap, decoders=require('cap').decoders, PROTOCOL=decoders.PROTOCOL
const zwiftProtoRoot = require('zwift-mobile-api/src/zwiftProtoBuf')
const buffer = new Buffer(65535)
const clientToServerPacket = zwiftProtoRoot.lookup('ClientToServer')
const serverToClientPacket = zwiftProtoRoot.lookup('ServerToClient')
class ZwiftPacketMonitor extends EventEmitter {
constructor (interfaceName) {
super()
this._cap = new Cap()
this._linkType = null
this._sequence = 0
if (interfaceName.match(/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/)) {
this._interfaceName = Cap.findDevice(interfaceName)
} else {
this._interfaceName = interfaceName
}
}
start () {
this._linkType = this._cap.open(this._interfaceName, 'port 3022', 10 * 1024 * 1024, buffer)
this._cap.setMinBytes && this._cap.setMinBytes(0)
this._cap.on('packet', this.processPacket.bind(this))
}
stop () {
this._cap.close()
}
static deviceList () {
return Cap.deviceList()
}
processPacket () {
if (this._linkType === 'ETHERNET') {
let ret = decoders.Ethernet(buffer)
if (ret.info.type === PROTOCOL.ETHERNET.IPV4) {
ret = decoders.IPV4(buffer, ret.offset)
if (ret.info.protocol === PROTOCOL.IP.UDP) {
ret = decoders.UDP(buffer, ret.offset)
try {
if (ret.info.srcport === 3022) {
let packet = serverToClientPacket.decode(buffer.slice(ret.offset, ret.offset + ret.info.length))
/*
if (this._sequence) {
if (packet.seqno > this._sequence + 1) {
console.warn(`Missing packets - expecting ${this._sequence + 1}, got ${packet.seqno}`)
} else if (packet.seqno < this._squence) {
console.warn(`Delayed packet - expecting ${this._sequence + 1}, got ${packet.seqno}`)
return
}
}
this._sequence = packet.seqno
*/
for (let player_state of packet.player_states) {
this.emit('incomingPlayerState', player_state, packet.world_time, ret.info.dstport, ret.info.dstaddr)
}
if (packet.num_msgs === packet.msgnum) {
this.emit('endOfBatch')
}
} else if (ret.info.dstport === 3022) {
let packet = clientToServerPacket.decode(buffer.slice(ret.offset, ret.offset + ret.info.length - 4))
if (packet.state) {
this.emit('outgoingPlayerState', packet.state, packet.world_time, ret.info.srcport, ret.info.srcaddr)
}
}
} catch (ex) {
console.log(ex)
}
}
}
}
}
}
module.exports = ZwiftPacketMonitor