diff --git a/channel.js b/channel.js
index 9aad63a6..af565ed4 100644
--- a/channel.js
+++ b/channel.js
@@ -19,6 +19,7 @@ var Logger = require("./logger.js");
var InfoGetter = require("./get-info.js");
var Server = require("./server.js");
var io = Server.io;
+var NWS = require("./notwebsocket");
var Rank = require("./rank.js");
var Auth = require("./auth.js");
var ChatCommand = require("./chatcommand.js");
@@ -760,6 +761,7 @@ Channel.prototype.sendRecentChat = function(user) {
Channel.prototype.sendAll = function(message, data) {
io.sockets.in(this.name).emit(message, data);
+ NWS.inRoom(this.name).emit(message, data);
}
Channel.prototype.broadcastPlaylistMeta = function() {
diff --git a/notwebsocket.js b/notwebsocket.js
new file mode 100644
index 00000000..8cee92f0
--- /dev/null
+++ b/notwebsocket.js
@@ -0,0 +1,118 @@
+const chars = "abcdefghijklmnopqsrtuvwxyz" +
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
+ "0123456789";
+
+
+var NotWebsocket = function() {
+ this.hash = "";
+ for(var i = 0; i < 30; i++) {
+ this.hash += chars[parseInt(Math.random() * (chars.length - 1))];
+ }
+
+ this.pktqueue = [];
+ this.handlers = {};
+ this.room = "";
+}
+
+NotWebsocket.prototype.emit = function(msg, data) {
+ //hack because something fishy is going on
+ if(typeof msg === "object") {
+ data = msg["1"];
+ msg = msg["0"];
+ }
+ var pkt = [msg, data];
+ this.pktqueue.push(pkt);
+}
+
+NotWebsocket.prototype.poll = function() {
+ var q = this.pktqueue;
+ this.pktqueue = [];
+ return q;
+}
+
+NotWebsocket.prototype.on = function(msg, callback) {
+ if(!(msg in this.handlers))
+ this.handlers[msg] = [];
+ this.handlers[msg].push(callback);
+}
+
+NotWebsocket.prototype.recv = function(urlstr) {
+ var msg, data;
+ try {
+ var js = JSON.parse(urlstr);
+ msg = js[0];
+ data = js[1];
+ }
+ catch(e) {
+ console.log("Failed to parse NWS string");
+ }
+ if(!msg)
+ return;
+ if(!(msg in this.handlers))
+ return;
+ for(var i = 0; i < this.handlers[msg].length; i++) {
+ this.handlers[msg][i](data);
+ }
+}
+
+NotWebsocket.prototype.join = function(rm) {
+ this.room = rm;
+}
+
+NotWebsocket.prototype.disconnect = function() {
+
+}
+
+function sendJSON(res, obj) {
+ var response = JSON.stringify(obj, null, 4);
+ if(res.callback) {
+ response = res.callback + "(" + response + ")";
+ }
+ var len = unescape(encodeURIComponent(response)).length;
+
+ res.setHeader("Content-Type", "application/json");
+ res.setHeader("Content-Length", len);
+ res.end(response);
+}
+
+var clients = {};
+function newConnection(req, res) {
+ var nws = new NotWebsocket();
+ clients[nws.hash] = nws;
+ sendJSON(res, nws.hash);
+ return nws;
+}
+exports.newConnection = newConnection;
+
+function msgReceived(req, res) {
+ var h = req.params.hash;
+ if(h in clients) {
+ if(req.params.str == "poll") {
+ sendJSON(res, clients[h].poll());
+ }
+ else {
+ clients[h].recv(unescape(req.params.str));
+ sendJSON(res, "");
+ }
+ }
+}
+exports.msgReceived = msgReceived;
+
+function inRoom(rm) {
+ var cl = [];
+ for(var h in clients) {
+ if(clients[h].room == rm) {
+ cl.push(clients[h]);
+ }
+ }
+
+ return {
+ emit: function() {
+ for(var i = 0; i < this.cl.length; i++) {
+ this.cl[i].emit(arguments);
+ }
+ },
+ cl: cl
+ };
+}
+exports.inRoom = inRoom;
diff --git a/server.js b/server.js
index 1676ad3a..5362237a 100644
--- a/server.js
+++ b/server.js
@@ -18,6 +18,7 @@ Logger.syslog.log("Starting CyTube v" + VERSION);
var Config = require("./config.js");
var express = require("express");
var API = require("./api.js");
+var NWS = require("./notwebsocket");
var app = express();
app.get("/r/:channel(*)", function(req, res, next) {
@@ -34,6 +35,53 @@ app.get("/api/:apireq(*)", function(req, res, next) {
API.handle(req.url.substring(5), req, res);
});
+function getClientIP(req) {
+ var ip;
+ var forward = req.header("x-forwarded-for");
+ if(forward) {
+ ip = forward.split(",")[0];
+ }
+ if(!ip) {
+ ip = req.connection.remoteAddress;
+ }
+ return ip;
+}
+
+app.get("/nws/connect", function(req, res, next) {
+ var socket = NWS.newConnection(req, res);
+ var ip = getClientIP(req);
+ if(Database.checkGlobalBan(ip)) {
+ Logger.syslog.log("Disconnecting " + ip + " - bant");
+ socket.emit("kick", {
+ reason: "You're globally banned!"
+ });
+ socket.disconnect(true);
+ return;
+ }
+ socket.on("disconnect", function() {
+ exports.clients[ip]--;
+ });
+ if(!(ip in exports.clients)) {
+ exports.clients[ip] = 1;
+ }
+ else {
+ exports.clients[ip]++;
+ }
+ if(exports.clients[ip] > Config.MAX_PER_IP) {
+ socket.emit("kick", {
+ reason: "Too many connections from your IP address"
+ });
+ socket.disconnect(true);
+ return;
+ }
+ var user = new User(socket, ip);
+ Logger.syslog.log("Accepted connection from /" + user.ip);
+});
+
+app.get("/nws/:hash/:str", function(req, res, next) {
+ NWS.msgReceived(req, res);
+});
+
app.get("/:thing(*)", function(req, res, next) {
res.sendfile(__dirname + "/www/" + req.params.thing);
});
diff --git a/www/assets/js/callbacks.js b/www/assets/js/callbacks.js
index 2c2201b5..b2f36ec1 100644
--- a/www/assets/js/callbacks.js
+++ b/www/assets/js/callbacks.js
@@ -835,6 +835,7 @@ Callbacks = {
}
}
+/*
$.getScript(IO_URL+"/socket.io/socket.io.js", function() {
try {
socket = io.connect(IO_URL);
@@ -846,3 +847,9 @@ $.getScript(IO_URL+"/socket.io/socket.io.js", function() {
Callbacks.disconnect();
}
});
+*/
+
+socket = new NotWebsocket();
+for(var key in Callbacks) {
+ socket.on(key, Callbacks[key]);
+}
diff --git a/www/assets/js/notwebsocket.js b/www/assets/js/notwebsocket.js
new file mode 100644
index 00000000..2add0ade
--- /dev/null
+++ b/www/assets/js/notwebsocket.js
@@ -0,0 +1,50 @@
+var NotWebsocket = function() {
+ this.connected = false;
+ $.getJSON(WEB_URL + "/nws/connect", function(data) {
+ this.hash = data;
+ this.connected = true;
+ this.recv(["connect", undefined]);
+ this.pollint = setInterval(function() {
+ this.poll();
+ }.bind(this), 100);
+ }.bind(this));
+
+ this.handlers = {};
+}
+
+NotWebsocket.prototype.emit = function(msg, data) {
+ if(!this.connected) {
+ setTimeout(function() {
+ this.emit(msg, data);
+ }.bind(this), 100);
+ }
+ var pkt = [msg, data];
+ var str = escape(JSON.stringify(pkt));
+ $.getJSON(WEB_URL+"/nws/"+this.hash+"/"+str, function(){});
+}
+
+NotWebsocket.prototype.on = function(msg, callback) {
+ if(!(msg in this.handlers))
+ this.handlers[msg] = [];
+ this.handlers[msg].push(callback);
+}
+
+NotWebsocket.prototype.poll = function() {
+ if(!this.connected)
+ return;
+ $.getJSON(WEB_URL+"/nws/"+this.hash+"/poll", function(data) {
+ for(var i = 0; i < data.length; i++) {
+ console.log("DBG", data[i]);
+ this.recv(data[i]);
+ }
+ }.bind(this));
+}
+
+NotWebsocket.prototype.recv = function(pkt) {
+ var msg = pkt[0], data = pkt[1];
+ if(!(msg in this.handlers))
+ return;
+ for(var i = 0; i < this.handlers[msg].length; i++) {
+ this.handlers[msg][i](data);
+ }
+}
diff --git a/www/channel.html b/www/channel.html
index a1977ff2..c3413473 100644
--- a/www/channel.html
+++ b/www/channel.html
@@ -313,6 +313,7 @@
+