pngs/server.js

347 lines
7.5 KiB
JavaScript

var Connect = require('connect');
var wss = require('websocket').server;
var wsc = require('websocket').client;
var irc = require('irc-js');
var frontend, sendToCensor;
/*
* Nedap backend connection
*/
/* TODO: url */
var nedap;
function connectNedap() {
var nedapClient = new wsc();
nedapClient.on('connect', function(conn) {
console.log('NEDAP opened');
nedap = conn;
nedap.sendUTF('nedap-RuJejdymmesAktiOdyitEdivRiectij');
nedap.on('close', function() {
console.log('NEDAP closed');
connectNedap();
});
nedap.on('error', function(e) {
console.log('NEDAP error: ' + e.message);
connectNedap();
});
nedap.on('message', function(wsmsg) {
try {
var msg = JSON.parse(wsmsg.utf8Data);
console.log({ fromNedap: msg });
if (msg.gif) {
sendToCensor(msg);
} else
sendToFrontend({ nedap: msg });
} catch (e) {
console.error(e.stack);
}
});
});
nedapClient.on('connectFailed', function(e) {
console.error(e.stack || e);
setTimeout(connectNedap, 1000);
});
nedapClient.connect('ws://nedap.c3d2.de:2342/', 'quiz-nedap');
}
connectNedap();
/*
* IRC client
*/
var IRC_SERVER = 'irc.hackint.eu';
var IRC_CHAN = '#pentanews';
function connectChat() {
var chat = new irc({ server: IRC_SERVER,
encoding: 'utf-8',
nick: '[Ceiling]Katze'
});
chat.connect();
chat.addListener('376', function() {
if (!chat)
return;
chat.join(IRC_CHAN);
});
chat.addListener('366', function(msg) {
if (!chat)
return;
if (msg.params[1] === IRC_CHAN) {
console.log('Successfully joined ' + IRC_CHAN);
pushIrcInfo();
}
});
chat.addListener('privmsg', function(msg) {
if (!chat)
return;
console.log({PRIVMSG:msg});
var nick = msg.person.nick;
var channel = msg.params[0];
var text = msg.params[1];
var sText = "", i;
for(i = 0; i < text.length; i++) {
if (text.charCodeAt(i) >= 32)
sText += text[i];
}
if (nick && channel === IRC_CHAN && sText && frontend) {
sendToFrontend({ irc: { nick: nick,
text: sText
} });
}
});
chat.addListener('disconnected', function() {
if (!chat)
return;
chat = undefined;
console.error('Chat disconnected!');
window.setTimeout(connectChat, 1000);
});
chat.on('error', connectChat);
}
connectChat();
function pushIrcInfo() {
sendToFrontend({ irc: { server: IRC_SERVER,
channel: IRC_CHAN } });
}
/*
* Buttons
*/
var buzz = new (require('./buzz_iface/node_lib/buzz').Buzz)('/dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A400gqnA-if00-port0');
buzz.on('button', function(key) {
console.log({button:key});
sendToFrontend({ buzzer: key });
});
function setAllLEDs(brightness) {
for(var player = 0; player < 3; player++)
buzz.set_led(player, brightness);
}
var MORSE_ALPHABET = {
"A": ". -",
"B": "- . . .",
"C": "- . - .",
"D": "- . .",
"E": ".",
"F": ". . - .",
"G": "- - .",
"H": ". . . .",
"I": ". .",
"J": ". - - -",
"K": "- . -",
"L": ". - . .",
"M": "- -",
"N": "- .",
"O": "- - -",
"P": ". - - .",
"Q": "- - . -",
"R": ". - .",
"S": ". . .",
"T": "-",
"U": ". . -",
"V": ". . . -",
"W": ". - -",
"X": "- . . -",
"Y": "- . - -",
"Z": "- - . .",
"0": "- - - - -",
"1": ". - - - -",
"2": ". . - - -",
"3": ". . . - -",
"4": ". . . . -",
"5": ". . . . .",
"6": "- . . . .",
"7": "- - . . .",
"8": "- - - . .",
"9": "- - - - .",
"À": ". - - . -",
"Å": ". - - . -",
"Ä": ". - . -",
"È": ". - . . -",
"É": ". . - . .",
"Ö": "- - - .",
"Ü": ". . - -",
"ß": ". . . - - . .",
"CH": "- - - -",
"Ñ": "- - . - -",
".": ". - . - . -",
",": "- - . . - -",
":": "- - - . . .",
";": "- . - . - .",
"?": ". . - - . .",
"-": "- . . . . -",
"_": ". . - - . -",
"(": "- . - - .",
")": "- . - - . -",
"'": ". - - - - .",
"=": "- . . . -",
"+": ". - . - .",
"/": "- . . - .",
"@": ". - - . - ."
};
var DIT_LENGTH = 100;
var DAH_LENGTH = 3 * DIT_LENGTH;
var PAUSE_LENGTH = DIT_LENGTH;
var CHARACTER_PAUSE_LENGTH = 3;
var WORD_PAUSE_LENGTH = 7;
function morse(text) {
/* Assemble sequence */
var sequence = '';
for(var i = 0; i < text.length; i++) {
var symbols;
if (text[i] === " ")
for(var j = 0; j < WORD_PAUSE_LENGTH; j++)
sequence += " ";
else if ((symbols = MORSE_ALPHABET[text[i].toLocaleUpperCase()])) {
sequence += symbols;
for(j = 0; j < CHARACTER_PAUSE_LENGTH; j++)
sequence += " ";
}
}
sequence += " "; /* clear led at end */
console.log("morse", text, sequence);
/* Play */
var playSequence = function() {
console.log("playSequence", sequence[0])
var delay;
switch(sequence[0]) {
case ".":
setAllLEDs(1);
delay = DIT_LENGTH;
break;
case "-":
setAllLEDs(1);
delay = DAH_LENGTH;
break;
case " ":
setAllLEDs(0);
delay = PAUSE_LENGTH;
break;
}
sequence = sequence.substr(1);
if (sequence && delay)
setTimeout(playSequence, delay);
};
playSequence();
}
/*
* Web server
*/
var server = Connect.createServer(
Connect.logger(),
Connect.bodyParser(),
Connect.static(__dirname, { maxAge: 1000 }),
Connect.errorHandler({ dumpExceptions: true, showStack: true })
);
/*
* WebSocket server
*/
var gamestate = {};
new wss({ httpServer: server }).on('request', function(req) {
var conn = req.accept(null, req.origin);
if (req.requestedProtocols && req.requestedProtocols.indexOf('censor') >= 0) {
/* Censor frontend */
sendToCensor = function(obj) {
conn.sendUTF(JSON.stringify(obj));
};
conn.on('message', function(wsmsg) {
console.log(wsmsg);
try {
var msg = JSON.parse(wsmsg.utf8Data);
if (msg.gif)
sendToFrontend(msg);
} catch (e) {
console.error(e.stack);
}
});
var reset = function() {
sendToCensor = function() { };
};
conn.on('close', reset);
conn.on('error', reset);
} else {
/* Game frontend */
frontend = conn;
conn.on('message', function(wsmsg) {
console.log(wsmsg);
try {
var msg = JSON.parse(wsmsg.utf8Data);
if (msg.nedap) {
console.log({ toNedap: msg.nedap });
if (nedap)
nedap.sendUTF(JSON.stringify(msg.nedap));
} else if (msg.irc === "activate") {
pushIrcInfo();
} else if (msg.buzzerLED) {
buzz.set_led(msg.buzzerLED[0], msg.buzzerLED[1]);
} else if (msg.morse) {
morse(msg.morse);
} else if (msg.gamestate) {
gamestate = msg.gamestate;
} else if (msg.requestGamestate) {
conn.sendUTF(JSON.stringify({ gamestate: gamestate }));
} else if (msg.tweet) {
tweet(msg.tweet);
}
} catch (e) {
console.error(e.stack);
}
});
var reset = function() {
frontend = null;
};
conn.on('close', reset);
conn.on('error', reset);
}
});
function sendToFrontend(obj) {
if (!frontend)
return;
frontend.sendUTF(JSON.stringify(obj));
}
server.listen(8081, "::1");
morse("c3d2");
var twit = new (require('twitter'))({
consumer_key: 'sNWvbrAz11vVMwppORKA',
consumer_secret: 'MzAhGlzz3qWUIxse8vcHc3zqkPOBuWKJgjazGkeOc',
access_token_key: '108923470-KVfqQJc8oIhAYZj2RhL7ggrR5Y9eMGjTQD79Db12',
access_token_secret: 'uQ9ljbh5L3NGEuHhKSrrnQv3KmL59d0nS2pJBjiqgL8'
});
function tweet(text) {
// FIXME: remove next line for production!
return;
twit.updateStatus(text, function(res) {
if (res.statusCode && res.statusCode >= 400) {
/* Failure */
var m = text.match(/^(.+) /);
if (m)
tweet(m[1]);
}
});
}