├── .gitignore ├── .ackrc ├── public ├── img │ ├── code.png │ ├── favicon.ico │ ├── loading.gif │ ├── rockets.png │ ├── computer.png │ └── launchpad.png ├── fonts │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.ttf │ └── glyphicons-halflings-regular.woff ├── js │ ├── admin.js │ ├── main.js │ ├── libs │ │ ├── mousetrap.min.js │ │ ├── alertify.min.js │ │ ├── favico.min.js │ │ ├── moment-2.1.0.min.js │ │ └── lodash-1.3.1.min.js │ ├── lobby.js │ └── game.js └── css │ ├── github.css │ ├── alertify.css │ └── style.css ├── .editorconfig ├── src ├── eventnet.js ├── db.js ├── settings.js.example.js ├── config.js ├── sockets.js ├── routes.js ├── server.js └── models.js ├── views ├── footer.jade ├── layout.jade ├── signup.jade ├── nav.jade ├── about.jade ├── index.jade ├── lobby.jade ├── game.jade └── admin.jade ├── runserver.js ├── TODO.md ├── MIT-LICENSE.txt ├── package.json ├── Gruntfile.js └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | backup 3 | src/settings.js 4 | -------------------------------------------------------------------------------- /.ackrc: -------------------------------------------------------------------------------- 1 | --ignore-dir=highlight.js 2 | --ignore-dir=public/js/libs 3 | -------------------------------------------------------------------------------- /public/img/code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/voithos/swiftcode/HEAD/public/img/code.png -------------------------------------------------------------------------------- /public/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/voithos/swiftcode/HEAD/public/img/favicon.ico -------------------------------------------------------------------------------- /public/img/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/voithos/swiftcode/HEAD/public/img/loading.gif -------------------------------------------------------------------------------- /public/img/rockets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/voithos/swiftcode/HEAD/public/img/rockets.png -------------------------------------------------------------------------------- /public/img/computer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/voithos/swiftcode/HEAD/public/img/computer.png -------------------------------------------------------------------------------- /public/img/launchpad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/voithos/swiftcode/HEAD/public/img/launchpad.png -------------------------------------------------------------------------------- /public/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/voithos/swiftcode/HEAD/public/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /public/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/voithos/swiftcode/HEAD/public/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /public/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/voithos/swiftcode/HEAD/public/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | 7 | indent_style = space 8 | indent_size = 4 9 | 10 | [package.json] 11 | indent_size = 2 12 | 13 | [Gruntfile.js] 14 | indent_size = 2 15 | -------------------------------------------------------------------------------- /src/eventnet.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var events = require('events'); 4 | 5 | var SwiftCODEEventNet = function() { 6 | }; 7 | 8 | SwiftCODEEventNet.prototype = new events.EventEmitter(); 9 | 10 | var enet = new SwiftCODEEventNet(); 11 | module.exports = enet; 12 | -------------------------------------------------------------------------------- /views/footer.jade: -------------------------------------------------------------------------------- 1 | .footer 2 | .container 3 | p.text-muted Made in 2014. Created for Pandacodium 2013. Graciously hosted by Heroku. 4 | a(href='https://github.com/voithos/swiftcode') 5 | span.forkme.label.label-success Fork me on GitHub 6 | -------------------------------------------------------------------------------- /src/db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var mongoose = require('mongoose'); 4 | 5 | module.exports.setupConnection = function(config) { 6 | // Connection string takes precedence 7 | if (config.dbconnectionstring) { 8 | mongoose.connect(config.dbconnectionstring); 9 | } else { 10 | mongoose.connect('mongodb://' + config.db.host + ':' + config.db.port + '/' + config.db.name, { 11 | user: config.db.username, 12 | pass: config.db.password 13 | }); 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /runserver.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | var forever = require('forever-monitor'); 3 | 4 | var server = new forever.Monitor('src/server.js', { 5 | options: process.argv.slice(2), 6 | watch: true, 7 | watchIgnorePatterns: ['.*/**', 'backup/**', 'public/**', 'views/**', '**.md'], 8 | watchDirectory: '.' 9 | }); 10 | 11 | server.on('watch:restart', function(info) { 12 | console.error(' restarting script because ' + info.file + ' changed'); 13 | }); 14 | server.on('restart', function() { 15 | console.error(' (time ' + server.times + ')'); 16 | }); 17 | server.on('exit:code', function(code) { 18 | if (code) { 19 | console.error(' script exited with code ' + code); 20 | } 21 | }); 22 | server.on('exit', function() { 23 | console.log('server.js exiting'); 24 | }); 25 | server.start(); 26 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | # TODO 2 | 3 | ### Core features 4 | * Spam protection in login process 5 | * Add automated tests to compare server-side typeable-detection with client-side typeable-to-DOM matching algorithm 6 | * Better anti-cheat 7 | * Add method to kick out inactive users 8 | * Allow single user to play multi-player, to allow multi-player to get started when few users are online. 9 | 10 | ### Bugs 11 | * Error occurs after unjoining (playerCursor set to null, never set back?) 12 | * Docstrings are not classified seperately by highlight.js, thus not excluded 13 | * Certain keys don't work under Opera (for example, underscore is treated as '-') 14 | * When multiple players join around the same time, some may not get "ingame:join" updates 15 | * Foreign keyboard don't work (Mousetrap problem?) 16 | 17 | ### Possible future features 18 | * Learning mode? (collaborate with 'Learn X in Y' project?) 19 | * Profile page, where user can see stats, tweak settings 20 | * Names / passwords / invitation-only option for game rooms 21 | * Training mode? ("beat your own time") 22 | * Badges / leaderboard? 23 | * Show statistics of opponents, after they win? 24 | -------------------------------------------------------------------------------- /src/settings.js.example.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var settings = {}; 4 | 5 | // Note: most of these configuration options can be overridden 6 | // with specific environment variables. See the README for details 7 | 8 | // HTTP server's (and WebSocket server's) settings 9 | // NOTE: Generally, you'll want to set the ipaddress to '0.0.0.0' when in 10 | // a production environment (search for INADDR_ANY for more info) 11 | settings.ipaddress = '127.0.0.1'; 12 | settings.port = 8080; 13 | 14 | // The secret salt used to generate session tokens. 15 | // Set this to a falsy value (i.e. null) 16 | // to have it be auto-generated on startup. 17 | settings.sessionSecret = ''; 18 | 19 | // Database settings 20 | settings.dbname = 'swiftcode'; 21 | settings.dbhost = 'localhost'; 22 | settings.dbport = 27017; // Default MongoDB port 23 | settings.dbusername = ''; 24 | settings.dbpassword = ''; 25 | 26 | // Database connection string, for convenience (if this is not falsy, it 27 | // will OVERRIDE the previous DB settings) 28 | settings.dbconnectionstring = null; 29 | 30 | module.exports = settings; 31 | -------------------------------------------------------------------------------- /MIT-LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Zaven Muradyan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /views/layout.jade: -------------------------------------------------------------------------------- 1 | !!! 2 | html 3 | head 4 | meta(charset='utf-8') 5 | title= title + ' | SwiftCODE' 6 | link(rel='shortcut icon', href='favicon.ico') 7 | link(rel='stylesheet', href='/css/bootstrap.css') 8 | link(rel='stylesheet', href='/css/alertify.css') 9 | link(rel='stylesheet', href='/css/style.css') 10 | block styles 11 | body 12 | include nav 13 | block content 14 | include footer 15 | script(src='//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js') 16 | script. 17 | if (!('jQuery' in window)) { 18 | document.write('