Permalink
Browse files

initialize

  • Loading branch information...
votre_pseudo
votre_pseudo committed Aug 4, 2011
0 parents commit 06680ab1c882d435b8c9ddefef4df47b5eea8ecf
@@ -0,0 +1,226 @@
+var host = "localhost";
+var port = 60000;
+var DEBUG = false;
+var net = require("net");
+var crypto = require('crypto');
+
+function pack(num) {
+ var result = '';
+ result += String.fromCharCode(num >> 24 & 0xFF);
+ result += String.fromCharCode(num >> 16 & 0xFF);
+ result += String.fromCharCode(num >> 8 & 0xFF);
+ result += String.fromCharCode(num & 0xFF);
+ return result;
+}
+
+function User(socket) {
+ this.username;
+ this.socket = socket;
+ this.opponent;
+ this.handshaked = false;
+ this.inGame = false;
+
+ this.handshake = function(data) {
+ d = data.toString("binary");
+ var _headers = d.split("\r\n");
+ var upgradeHead = _headers[ _headers.length - 1 ];
+ var sec1_regex = /Sec-WebSocket-Key1: (.*)\r\n/g;
+ var sec2_regex = /Sec-WebSocket-Key2: (.*)\r\n/g;
+ var origin_regex = /Origin: (.*)\r\n/g;
+ var host_regex = /Host: (.*)\r\n/g;
+ var ressource_regex = /GET (.*) HTTP/g;
+ var protocol_regex = /Sec-WebSocket-Protocol: (.*)/g;
+ var host = host_regex.exec(d)[1];
+ var ressource = ressource_regex.exec(d)[1];
+ var origin = origin_regex.exec(d)[1];
+ var key1 = sec1_regex.exec(d)[1];
+ var num1 = parseInt(key1.replace(/[^\d]/g, ""), 10)
+ var key2 = sec2_regex.exec(d)[1];
+ var num2 = parseInt(key2.replace(/[^\d]/g, ""), 10);
+ var spaces1 = key1.replace(/[^\ ]/g, "").length;
+ var spaces2 = key2.replace(/[^\ ]/g, "").length;
+ if (spaces1 == 0 || spaces2 == 0 || num1 % spaces1 != 0 || num2 % spaces2 != 0) {}
+ var hash = crypto.createHash("md5");
+ var kkkey1 = pack(parseInt(num1/spaces1));
+ var kkkey2 = pack(parseInt(num2/spaces2));
+ hash.update(kkkey1);
+ hash.update(kkkey2);
+ hash.update(upgradeHead);
+ this.socket.write("HTTP/1.1 101 Web Socket Protocol Handshake\r\n"
+ + "Upgrade: WebSocket\r\n"
+ + "Connection: Upgrade\r\n"
+ + "Sec-WebSocket-Origin: "+origin+"\r\n" // Local sandbox
+ + "Sec-WebSocket-Location: ws://"+host+ressource+"\r\n\r\n"
+ + hash.digest("binary"), "binary");
+ this.handshaked = true;
+ log("Handshake done");
+ };
+
+ this.send = function(msg) {
+ say("> "+msg);
+ this.socket.write(String.fromCharCode(0)+msg+String.fromCharCode(255), "binary");
+ };
+}
+
+var sockets = [];
+var users = [];
+
+var s = net.Server(function(socket) {
+ sockets.push(socket);
+
+ socket.addListener("connect", function() {
+ log("CONNECT");
+ var user = new User(this);
+ users.push(user);
+ });
+
+ socket.on("data", function(d) {
+ var user = getUserBySocket(this);
+ if (user.handshaked) {
+ process(user, d);
+ } else {
+ user.handshake(d);
+ }
+ });
+
+ socket.on("end", function() {
+ for (var i in users) {
+ if (users[i].socket == socket) {
+ var username = users[i].username;
+ var opponent = users[i].opponent;
+ if (opponent) {
+ opponent.inGame = false;
+ opponent.opponent = null;
+ opponent.send('{"cmd":"opponent_has_left"}');
+ }
+ users.splice(i, 1);
+ if (username) {
+ broadcast('{"cmd":"logout", "username":"'+username+'"}');
+ }
+ break;
+ }
+ }
+ });
+});
+
+function broadcast(msg) {
+ for (var i in users) {
+ users[i].send(msg);
+ }
+}
+
+function process(user, data) {
+ var d = data.toString().substring(1, data.toString().length-1);
+ say("< "+d);
+ var json = eval("("+d+")");
+ switch (json.cmd) {
+ case "connect":
+ // The server accept only two person !
+ if (users.length >= 300000) {
+ user.send('{"cmd":"error", "msg":"The server accept only two players !"}');
+ user.socket.end();
+ return;
+ }
+ // Close the connection if the username is invalid.
+ var usrname_rgx = new RegExp(/^[a-zA-Z0-9]{3,15}$/g);
+ if (!json.username.match(usrname_rgx)) {
+ user.send('{"cmd":"error", "msg":"Username must be 3 to 15 alphanum chars."}');
+ user.socket.end();
+ return;
+ }
+ // Close the connection if the username is already taken.
+ for (var i in users) {
+ if (users[i].username == json.username) {
+ user.send('{"cmd":"error", "msg":"Username already taken."}');
+ user.socket.end();
+ return;
+ }
+ }
+
+ user.username = json.username;
+
+ var t = {"cmd":"test", "users":[]};
+ for (var i in users)
+ if (users[i].username != user.username)
+ t.users.push(users[i].username);
+ user.send(JSON.stringify(t));
+ broadcast('{"cmd":"login", "username":"'+json.username+'"}');
+ break;
+ case "challenge":
+ if (user.username == json.user) {
+ user.send('{"cmd":"error", "msg":"You cannot challenge yourself."}');
+ return;
+ }
+
+ var opponent = getUserByUsername(json.user);
+ if (opponent == -1) {
+ user.send('{"cmd":"error", "msg":"This user does not exist."}');
+ return;
+ }
+
+ if (opponent.inGame) {
+ user.send('{"cmd":"error", "msg":"This user is actually in a game."}');
+ return;
+ }
+
+ opponent.send('{"cmd":"challenge", "user":"'+user.username+'"}');
+ break;
+ case "challengeRes":
+ var u1 = getUserByUsername(json.user);
+ if (json.res == "no") {
+ u1.send('{"cmd":"error", "msg":"'+user.username+' refuse to challenge you."}');
+ return;
+ }
+
+ if (u1.inGame) {
+ user.send('{"cmd":"error", "msg":"'+u1.username+' is already in a game."}');
+ return;
+ }
+
+ if (json.res == "yes") {
+ u1.inGame = true;
+ user.inGame = true;
+ u1.send('{"cmd":"setPlayer", "username":"'+user.username+'", "team":"red"}');
+ user.send('{"cmd":"setPlayer", "username":"'+user.username+'", "team":"silver"}');
+ user.opponent = u1;
+ u1.opponent = user;
+ u1.send('{"cmd":"opponent_has_logged"}');
+ }
+ break;
+ case "init_game":
+ user.send('{"cmd":"game", "game": {"player":"red", "turns":1}, "lastMove": null }');
+ user.opponent.send(d);
+ break;
+ case "message":
+ if (trim(json.msg) == "") return;
+ broadcast('{"cmd":"message", "msg":"'+user.username+': '+json.msg+'"}');
+ break;
+ case "game":
+ user.opponent.send(d);
+ break;
+ default:
+ broadcast(d);
+ break;
+ }
+}
+
+function getUserByUsername(username) {
+ for (var i in users)
+ if (users[i].username == username)
+ return users[i];
+ return -1;
+}
+
+function getUserBySocket(socket) {
+ for (var i in users)
+ if (users[i].socket == socket)
+ return users[i];
+}
+
+s.listen(port, host);
+say("Server listen on "+host+":"+port);
+say(""+new Date()+"\n");
+
+function say(msg) { console.log(msg); }
+function log(msg) { if (DEBUG) console.log(msg); }
+function trim(str) { return str.replace(/^\s+/g, '').replace(/\s+$/g, ''); }
@@ -0,0 +1,52 @@
+/* v1.0 | 20080212 */
+
+html, body, div, span, applet, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+a, abbr, acronym, address, big, cite, code,
+del, dfn, em, font, img, ins, kbd, q, s, samp,
+small, strike, strong, sub, sup, tt, var,
+b, u, i, center,
+dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ outline: 0;
+ font-size: 100%;
+ vertical-align: baseline;
+ background: transparent;
+}
+body {
+ line-height: 1;
+}
+ol, ul {
+ list-style: none;
+}
+blockquote, q {
+ quotes: none;
+}
+blockquote:before, blockquote:after,
+q:before, q:after {
+ content: '';
+ content: none;
+}
+
+/* remember to define focus styles! */
+:focus {
+ outline: 0;
+}
+
+/* remember to highlight inserts somehow! */
+ins {
+ text-decoration: none;
+}
+del {
+ text-decoration: line-through;
+}
+
+/* tables still need 'cellspacing="0"' in the markup */
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
@@ -0,0 +1,76 @@
+html, body {
+ font-family: 'Lucida Grande', Helvetica, Arial, Verdana, sans-serif;
+ font-size: 14px;
+ line-height: 21px;
+}
+
+h1 {
+ margin: 15px 0;
+ font-size: 19px;
+ line-height: 23px;
+}
+h2 {
+ margin: 20px 0 7px 0;
+ font-size: 15px;
+ line-height: 23px;
+}
+
+p {
+ margin: 10px 15px;
+}
+
+a { color: green; }
+a:hover { color: blue; }
+
+label {
+ width: 100px;
+ display: block;
+ float: left;
+}
+
+#page {
+ margin-top: 20px;
+ margin-left: 20px;
+}
+
+#page div.left {
+ float: left;
+}
+
+#page div.right {
+ float: left;
+ padding-left: 20px;
+}
+
+.clearleft { clear: left; }
+
+#options {
+ display: block;
+ border: 0px solid red;
+}
+#ckbConfirm {
+ float: left;
+}
+
+.nofloat {
+ float: none;
+ width: auto;
+}
+
+#txtLog {
+ display: block;
+ overflow-y: scroll;
+ width: 400px;
+ height: 270px;
+ border: 1px solid black;
+}
+#txtLog p {
+ margin: 0 5px;
+ border-bottom: 1px solid gray;
+}
+#txtLog span.server {
+ color: gray;
+}
+#txtLog span.error {
+ color: red;
+}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Oops, something went wrong.

0 comments on commit 06680ab

Please sign in to comment.