torinet
Version:
154 lines (124 loc) • 4.71 kB
JavaScript
const socketIO = require("socket.io");
const EventEmitter = require("events").EventEmitter;
const ip = require("ip");
const randomItem = require("random-item");
const _ = require("lodash");
const aes256 = require("aes256");
/*
{
name: "test",
connections: [ ... ],
next: "NEXT_IP",
@password: "PASSWORD"
}
*/
function nextGenerate (connections) {
let ips = [];
for (let connection of connections) {
ips.push(connection.ip);
}
if (connections.length !== 2) {
return randomItem(ips);
} else {
return ips[1];
}
}
function start (name, username, password = "%NONE%", state = {}) {
const io = socketIO();
const server = new EventEmitter();
if (_.isEmpty(state)) {
let user = {
name: username,
ip: ip.address()
}
state.name = name;
state.connections = [];
state.connections.push(user);
if (password !== "%NONE%") {
state.password = password;
}
}
let localStateInterval = setInterval(() => server.emit("state", state), 1000);
process.on("exit", () => clearInterval(localStateInterval));
state.next = nextGenerate(state.connections);
io.on("connection", client => {
const clientIp = client.handshake.address.split(":")[3];
server.emit("connection", clientIp);
let stateInterval = null;
client.on("checkConnection", () => {
client.emit("signal", {
ip: ip.address(),
secure: password !== "%NONE%",
name: name
});
});
client.on("pushMessage", (text) => {
let sender = "";
for (let connection of state.connections) {
if (connection.ip === clientIp) {
sender = connection.name;
break;
}
}
client.broadcast.emit("newMessage", { sender, text });
if (password !== "%NONE%") {
text = aes256.decrypt(password, text);
}
server.emit("message", { sender, text });
});
server.on("message", (text) => {
if (password !== "%NONE%") {
text = aes256.encrypt(password, text);
}
client.broadcast.emit("newMessage", { username, text });
})
client.on("auth", (user) => {
if (password !== "%NONE%") {
if (user.password === password) {
state.connections.push({
name: user.name,
ip: clientIp
});
state.next = nextGenerate(state.connections);
client.emit("checkAuth", { success: true });
stateInterval = setInterval(() => client.emit("state", state), 1000);
server.emit("auth", user.name);
client.emit("joined", user.name);
client.broadcast.emit("joined", user.name);
} else {
client.emit("checkAuth", { success: false });
client.disconnect();
}
} else {
state.connections.push({
name: user.name,
ip: clientIp
});
state.next = nextGenerate(state.connections);
client.emit("checkAuth", { success: true });
stateInterval = setInterval(() => client.emit("state", state), 1000);
server.emit("auth", user.name);
client.emit("joined", user.name);
client.broadcast.emit("joined", user.name);
}
});
client.on("disconnect", () => {
let newConnections = [];
for (let connection of state.connections) {
if (clientIp !== connection.ip) {
newConnections.push(connection);
client.emit("leave", connection.name);
client.broadcast.emit("leave", connection.name);
}
}
state.connections = newConnections;
state.next = nextGenerate(state.connections);
clearInterval(stateInterval)
server.emit("disconnect", clientIp)
});
});
io.listen(13785);
process.on("exit", () => io.close());
return server;
}
module.exports = start;