ソースを参照

Initial commit

k4be 1 ヶ月 前
コミット
9902a1fd09
2 ファイル変更116 行追加0 行削除
  1. 103 0
      index.js
  2. 13 0
      package.json

+ 103 - 0
index.js

@@ -0,0 +1,103 @@
+const net = require('net');
+const readline = require('readline');
+
+const HOST = 'localhost';
+const PORT = 6667;
+
+const sessions = new Set();
+
+function randomNick(len = 8) {
+  let nick = '';
+  for (let i = 0; i < len; i++) {
+    nick += String.fromCharCode(97 + Math.floor(Math.random() * 26));
+  }
+  return nick;
+}
+
+function createSession() {
+  const nick = randomNick();
+  const socket = net.createConnection({ host: HOST, port: PORT });
+  let buffer = '';
+
+  const session = { socket, nick };
+
+  socket.on('connect', () => {
+    socket.write(`NICK ${nick}\r\n`);
+    socket.write(`USER ${nick} 0 * :${nick}\r\n`);
+    console.log(`[+] Connected: ${nick}`);
+  });
+
+  socket.on('data', (data) => {
+    buffer += data.toString();
+    let lines = buffer.split('\r\n');
+    buffer = lines.pop();
+    for (const line of lines) {
+      if (line.startsWith('PING')) {
+        const token = line.slice(5);
+        socket.write(`PONG ${token}\r\n`);
+      }
+    }
+  });
+
+  socket.on('close', () => {
+    console.log(`[-] Disconnected: ${nick}`);
+    sessions.delete(session);
+  });
+
+  socket.on('error', (err) => {
+    console.log(`[!] Error (${nick}): ${err.message}`);
+  });
+
+  sessions.add(session);
+  return session;
+}
+
+function destroySession(session) {
+  session.socket.destroy();
+  sessions.delete(session);
+}
+
+function setCount(target) {
+  const current = sessions.size;
+  if (target > current) {
+    for (let i = 0; i < target - current; i++) createSession();
+  } else if (target < current) {
+    const toRemove = [...sessions].slice(target);
+    for (const s of toRemove) destroySession(s);
+  }
+}
+
+function sendAll(message) {
+  for (const s of sessions) {
+    s.socket.write(`${message}\r\n`);
+  }
+}
+
+// Start with one connection
+createSession();
+
+const rl = readline.createInterface({ input: process.stdin });
+
+rl.on('line', (line) => {
+  line = line.trim();
+  if (!line) return;
+
+  if (line === 'exit') {
+    for (const s of [...sessions]) destroySession(s);
+    process.exit(0);
+  }
+
+  const num = Number(line);
+  if (!isNaN(num) && line !== '') {
+    setCount(Math.max(0, Math.floor(num)));
+    console.log(`[*] Sessions: ${sessions.size}`);
+  } else {
+    sendAll(line);
+    console.log(`[>] Sent to ${sessions.size} session(s): ${line}`);
+  }
+});
+
+rl.on('close', () => {
+  for (const s of [...sessions]) destroySession(s);
+  process.exit(0);
+});

+ 13 - 0
package.json

@@ -0,0 +1,13 @@
+{
+  "name": "irc-clone",
+  "version": "1.0.0",
+  "description": "",
+  "main": "index.js",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "keywords": [],
+  "author": "",
+  "license": "ISC",
+  "type": "commonjs"
+}