From 9be3ecd4eeb4e0481bb9ce2ee0ca5a5b2d754342 Mon Sep 17 00:00:00 2001 From: tomsmeding Date: Tue, 21 Apr 2015 16:28:26 +0200 Subject: Initial --- chatserver.js | 165 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100755 chatserver.js (limited to 'chatserver.js') diff --git a/chatserver.js b/chatserver.js new file mode 100755 index 0000000..0529630 --- /dev/null +++ b/chatserver.js @@ -0,0 +1,165 @@ +#!/usr/bin/env node +var fs=require("fs"), + http=require("http"), + WebSocketServer=require("ws").Server, + CircularBuffer=require("circular-buffer"); +var HTTPPORT=81,WSPORT=8000; + + +////////// WEBSOCKETS ////////// + +function uniqid(){ + if(!uniqid.$)uniqid.$=1; + return uniqid.$++; +} + +var users=[]; +var lobbies=[]; + +function lobby_create(lname){ + lobbies.push({id:uniqid(),name:lname,users:[],history:new CircularBuffer(10)}); +} + +["a_lobby","lobby_2"].forEach(lobby_create); + +new WebSocketServer({port:WSPORT}).on("connection",function(ws){ + var uobj; + (function(){ + var nick="_user"+uniqid(); + while(fnick(nick)!=-1)nick="_user"+uniqid(); + uobj=new UserObject(nick,ws); + })(); + users.push(uobj); + ws.send("#yournick "+uobj.nick); + ws.on("message",function(msg,flags){ + console.log("("+uobj.id+","+uobj.nick+"): "+msg); + if(msg.match(/^#lobby /)){ + var which=parseInt(msg.slice(7),10),lobidx=flob(which),oldlobidx; + if(lobidx==-1){ + ws.send("#error Invalid lobby"); + return; + } + ws.send("#lobby "+which); + if(uobj.lob!=null){ + oldlobidx=flob(uobj.lob); + lobbies[oldlobidx].users.splice(lobfuser(lobbies[oldlobidx],uobj.id),1); + lobbysend(lobbies[oldlobidx],"#part "+uobj.nick); + lobbies[oldlobidx].history.push(["part",uobj.nick]); + } + uobj.lob=which; + lobbies[lobidx].users.push(uobj.id); + lobbysend(lobbies[lobidx],"#join "+uobj.nick); + lobbies[lobidx].history.push(["join",uobj.nick]); + uobj.ws.send("#historystart"); + lobbies[lobidx].history.toarray().forEach(function(h){ + uobj.ws.send("#history "+h.join(" ")); + }); + uobj.ws.send("#historyend"); + } else if(msg.match(/^#nick /)){ + var choice=msg.slice(6).replace(/[\x00-\x20\x7F\x80-\xFF]/g,""); //all shitty characters including space (' ') + var i; + if(choice.length==0){ + ws.send("#error Invalid nick"); + return; + } + if(uobj.lob!=null){ + if(fnick(choice)!=-1){ + i=1; + while(fnick(choice+i)!=-1)i++; + choice+=i; + } + lobbysend(lobbies[flob(uobj.lob)],"#nick "+uobj.nick+" "+choice); + } + uobj.nick=choice; + } else if(msg.match(/^#lobbylist/)){ + ws.send("#lobbylist "+lobbies.map(function(lob){return lob.id+":"+lob.name;}).join(" ")); + } else if(msg.match(/^#nicklist/)){ + if(this.lob==null){ + ws.send("#error Cannot request nicklist while not in a lobby"); + return; + } + ws.send("#nicklist "+lobbies[flob(uobj.lob)].users.map(function(usr){ + return users[fuser(usr)].nick; + }).join(" ")); + } else if(msg[0]==">"){ //message! + var lobidx; + if(uobj.lob==null){ + ws.send("#error Cannot send message while not in a lobby"); + return; + } + lobidx=flob(uobj.lob); + lobbysend(lobbies[lobidx],"<"+uobj.nick+" "+msg.slice(1)); + lobbies[lobidx].history.push([">",uobj.nick,msg.slice(1)]); + } else { + ws.send("#error Invalid message starting with \""+msg.slice(0,10)+"\""); + return; + } + }); + ws.on("close",function(){ + var lobidx; + if(uobj.lob!=null){ + lobidx=flob(uobj.lob); + lobbysend(lobbies[lobidx],"#part "+uobj.nick,[uobj.id]); + lobbies[lobidx].history.push(["part",uobj.nick]); + lobbies[lobidx].users.splice(lobfuser(lobbies[lobidx],uobj.id),1); + } + users.splice(fuser(uobj.id),1); + }); +}); +console.log("Websocket server started on port "+WSPORT+"."); + +function UserObject(nick,ws){ + if(!(this instanceof UserObject))return new UserObject(nick,ws); + this.id=uniqid(); + this.nick=nick; + this.ws=ws; + this.lob=null; +} + +function lobbysend(lob,msg,exceptids){ + var uidx; + if(exceptids==undefined)exceptids=[]; + for(var i=0;i