const WebSocket = require('ws'); function sleep(ms) { return new Promise(r => setTimeout(r, ms)); } function rand(min, max) { return Math.floor(Math.random() * (max - min + 1) + min); } let nextMsgId = 1; async function handleSocket(socket) { let nick = 'nick' + nextMsgId++; let mask = nick + '!' + nick + '@host.net'; let w = (line) => { let d = (new Date()).toISOString(); let out = line .replace('$nick', nick) .replace('$mask', mask); out = `@msgid=${nextMsgId++};time=${d}; ${out}`; socket.send(out); } let joinChannel = async (chan) => { let users = []; w(`:$mask JOIN ${chan}`); while(true) { await sleep(rand(100, 700)); // 25% chance of joining a user if (users.length < 1000 && rand(1, 100) < 25) { let newNick = 'user' + nextMsgId++; users.push(newNick); w(`:${newNick}!${newNick}@host.net JOIN ${chan}`); } // 2% chance of parting a user if (users.length > 3 && rand(1, 100) < 2) { let idx = rand(0, users.length-1); let partedUser = users.splice(idx, 1); w(`:${partedUser}!${partedUser}@host.net PART ${chan}`); } let from = users[rand(0, users.length-1)]; w(`:${from}!${from}@host.net PRIVMSG ${chan} :some message`); } }; await sleep(1000); w(':srv.net 001 $nick :Welcome to the flood net'); w(':srv.net 005 $nick ACCEPT=30 AWAYLEN=200 CALLERID=g CASEMAPPING=ascii CHANLIMIT=#:20 CHANMODES=Zbegw,k,FHJdfjl,BCDMNOPRScimnprstuz CHANNELLEN=64 CHANTYPES=# ELIST=CMNTU ESILENCE=CcdiNnPpTtx EXCEPTS=e EXTBAN=,BCNORSUacjmrsz :are supported by this server'); w(':srv.net 005 $nick EXTJWT=1 HOSTLEN=64 KEYLEN=32 KICKLEN=255 LINELEN=512 MAXLIST=begw:100 MAXTARGETS=20 MODES=20 MONITOR=30 NAMESX NETWORK=floodnet NICKLEN=30 :are supported by this server'); w(':srv.net 375 $nick :srv.net of the day'); w(':srv.net 372 $nick :the motd'); w(':srv.net 376 $nick :End of message of the day'); joinChannel('#chan1'); joinChannel('#chan2'); joinChannel('#chan3'); } const server = new WebSocket.Server({ port: 10666 }); server.on('connection', handleSocket);