Skip to content

Instantly share code, notes, and snippets.

@psykzz
Created November 4, 2020 21:39
Show Gist options
  • Save psykzz/5239238b23f92a5c7e43609e0104edeb to your computer and use it in GitHub Desktop.
Save psykzz/5239238b23f92a5c7e43609e0104edeb to your computer and use it in GitHub Desktop.
Update smart-home lights via amongus capture
const { Discovery, Control } = require('magic-home');
const port = process.env.PORT || 8090;
const io = require('socket.io')(port);
const discovery = new Discovery();
const PlayerName = 'Fax';
/*
Color mapping
These are taken from simply using paint and getting the colors via the color picker.
Black, brown colors are definitely terrible colors (mostly show as white)
*/
const AmongUsColorMapping = [
[198, 17, 17], // red
[19, 45, 210], // blue
[17, 108, 35], // green
[238, 84, 187], // pink
[240, 125, 13], // orange
[246, 246, 87], // yellow
[63, 71, 78], // black
[255, 255, 255], // white
[107, 48, 188], // purple
[133, 73, 30], // brown
[56, 255, 221], // cyan
[80, 240, 57], // lime
];
// Small helper to sleep
function sleep(ms) {
return new Promise(resolve => {
setTimeout(resolve, ms);
});
}
// Look for the lights
async function findLights(scanTime = 500) {
return (await discovery.scan(scanTime)).map(
device => new Control(device.address)
);
}
let working = false;
async function setColor(lights, color) {
// Lights wait on a lock to ensure only one command excutes at a time.
while (working) {
await sleep(10);
}
working = true;
const [r, g, b] = AmongUsColorMapping[color];
// Sometimes we don't find a light
if (!lights.length) {
return;
}
lights.forEach(light => {
light.setColor(r, g, b, () => console.log);
});
// Reset the lock
working = false;
}
function runServer(lights) {
io.on('connection', socket => {
let lastData = {};
console.log('New connection / socket');
socket.on('connectCode', data => {
// This is the path of the aucapture param,
/* aaaabbbb (its just a string) */
// console.log('connectCode', { data });
});
socket.on('lobby', data => {
// This pretty much just contains information about the current lobby,
/*{"LobbyCode":"ONOSIF","Region":2}*/
// console.log('lobby', { data });
});
socket.on('state', data => {
// Contains current game state
/* 3 (literally just a number) */
// console.log('state', { data });
});
socket.on('player', data => {
// Contains player state information
/* {"Action":0,"Name":"Banana man","IsDead":false,"Disconnected":false,"Color":5} */
// console.log('player', { data });
if (data === lastData) {
// aucapture seems to send the same event twice. This avoids us overloading the lights
return;
}
lastData = data;
let { Name, Color } = JSON.parse(data);
if (Name !== PlayerName) {
return;
}
setColor(lights, Color);
});
});
}
function run() {
const lights = findLights(1000);
runServer(lights);
console.log(`Run among us capture, then hit the following url`);
console.log(`aucapture://localhost:8090/aaaabbbb?insecure`);
}
run();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment