142 lines
3.6 KiB
JavaScript
142 lines
3.6 KiB
JavaScript
|
|
let data = {
|
|
clients: {},
|
|
|
|
// Key: Controller
|
|
// Value: Controlee
|
|
// Music is played on Value's device.
|
|
control: {}
|
|
}
|
|
|
|
function getSocketByDevice (devid) {
|
|
for (let id in data.clients) {
|
|
let sock = data.clients[i]
|
|
if (sock.device && sock.device === devid) {
|
|
return sock
|
|
}
|
|
}
|
|
|
|
return null
|
|
}
|
|
|
|
function getControlling (sockid) {
|
|
for (let id in data.control) {
|
|
let cl = data.control[id]
|
|
if (cl === sockid) return id
|
|
}
|
|
|
|
return null
|
|
}
|
|
|
|
function start (io) {
|
|
io.on('connection', function (socket) {
|
|
let sockid = socket.id
|
|
|
|
socket.on('auth', function (device) {
|
|
if (getSocketByDevice(device) != null) {
|
|
return socket.emit('cerr', {error: 'devexists', code: 0})
|
|
}
|
|
|
|
socket.device = device
|
|
data.clients[sockid] = socket
|
|
})
|
|
|
|
socket.on('req:devs', function () {
|
|
let devices = []
|
|
|
|
for (let i in data.clients) {
|
|
let cl = data.clients[i]
|
|
if (cl.device === socket.device) continue
|
|
devices.push(devices)
|
|
}
|
|
|
|
socket.emit('res:devs', devices)
|
|
})
|
|
|
|
// Controller wants to take control of Controlee
|
|
socket.on('ctrl:connect', function (ctrlee) {
|
|
let dev = getSocketByDevice(ctrlee)
|
|
if (!dev) return socket.emit('cerr', {error: 'devnull', code: 1})
|
|
|
|
// Device is already controlling/being controlled
|
|
if (data.control[sockid] || getControlling(dev.id)) return socket.emit('cerr', {error: 'devctrl', code: 2})
|
|
|
|
dev.emit('ctrl:connect', { device: socket.device })
|
|
socket.emit('targ:success', { device: ctrlee })
|
|
})
|
|
|
|
// Disconnect
|
|
socket.on('ctrl:disconnect', function (ctrlee) {
|
|
let id, ctrl
|
|
if (getControlling(sockid)) {
|
|
// If this is a controlee, disconnect from controller
|
|
id = getControlling(sockid)
|
|
ctrl = data.clients[id]
|
|
|
|
delete data.control[id]
|
|
} else if (data.control[sockid]) {
|
|
// If this is a controller, disconnect from controlee
|
|
id = data.control[sockid]
|
|
ctrl = data.clients[id]
|
|
|
|
delete data.control[sockid]
|
|
}
|
|
|
|
if (!ctrl) return
|
|
|
|
ctrl.emit('targ:disconnect', {})
|
|
})
|
|
|
|
let directpass = ['track', 'pause', 'seek', 'volume', 'mute', 'queue', 'req:queue', 'res:queue']
|
|
for (let i in directpass) {
|
|
let syn = 'sync:' + directpass[i]
|
|
|
|
// Set pause/play state
|
|
// Sent from controlee to controller
|
|
socket.on(syn, function (data) {
|
|
let ctrl
|
|
|
|
if (getControlling(sockid)) {
|
|
// If this is a controlee, send to controller
|
|
ctrl = data.clients[getControlling(sockid)]
|
|
} else if (data.control[sockid]) {
|
|
// If this is a controller, send to controlee
|
|
ctrl = data.clients[data.control[sockid]]
|
|
}
|
|
|
|
ctrl && ctrl.emit('set:' + directpass[i], data)
|
|
})
|
|
}
|
|
|
|
// Synchronize timestamp
|
|
socket.on('sync:time', function (data) {
|
|
if (!getControlling(sockid)) return
|
|
let ctrl = data.clients[getControlling(sockid)]
|
|
ctrl && ctrl.emit('sync:time', data)
|
|
})
|
|
|
|
socket.on('disconnect', function () {
|
|
if (data.clients[sockid]) {
|
|
let dev = data.clients[sockid]
|
|
|
|
// Controller loses connection
|
|
// Emit to controlee
|
|
if (data.control[sockid]) {
|
|
let clt = data.clients[sockid]
|
|
clt && clt.emit('ctrl:disconnect', {})
|
|
|
|
// Controlee loses connection
|
|
// Emit to controller
|
|
} else if (getControlling(sockid)) {
|
|
let clt = data.clients[getControlling(sockid)]
|
|
clt && clt.emit('targ:disconnect', {})
|
|
}
|
|
|
|
delete data.clients[sockid]
|
|
}
|
|
})
|
|
})
|
|
}
|
|
|
|
module.exports = { start }
|