diff --git a/public/js/controllers/footerCtrl.js b/public/js/controllers/footerCtrl.js index 6541f6f70f..bcdd7ea6a5 100644 --- a/public/js/controllers/footerCtrl.js +++ b/public/js/controllers/footerCtrl.js @@ -1,6 +1,7 @@ "use strict"; -habitrpg.controller("FooterCtrl", ['$scope', '$rootScope', 'User', '$http', 'Notification', 'API_URL', +(typeof habitrpg !== 'undefined' ? habitrpg : habitrpgStatic) + .controller("FooterCtrl", ['$scope', '$rootScope', 'User', '$http', 'Notification', 'API_URL', function($scope, $rootScope, User, $http, Notification, API_URL) { /** @@ -13,17 +14,14 @@ habitrpg.controller("FooterCtrl", ['$scope', '$rootScope', 'User', '$http', 'Not // Stripe $.getScript('//checkout.stripe.com/v2/checkout.js'); - // Amazon Affiliate -// if ($rootScope.authenticated() && !User.user.purchased.ads) { -// $.getScript('//wms.assoc-amazon.com/20070822/US/js/link-enhancer-common.js?tag=ha0d2-20').fail(function() { -// $('body').append(''); -// }); -// } - // Google Analytics, only in production if (window.env.NODE_ENV === 'production') { - window._gaq = [["_setAccount", "UA-33510635-1"], ["_setDomainName", "habitrpg.com"], ["_trackPageview"]]; - $.getScript(("https:" === document.location.protocol ? "https://ssl" : "http://www") + ".google-analytics.com/ga.js"); + (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ + (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), + m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) + })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); + ga('create', 'UA-33510635-1', 'habitrpg.com'); + ga('send', 'pageview'); } // Scripts only for desktop @@ -44,27 +42,30 @@ habitrpg.controller("FooterCtrl", ['$scope', '$rootScope', 'User', '$http', 'Not /** * Debug functions. Note that the server route for gems is only available if process.env.DEBUG=true */ - $scope.addMissedDay = function(){ - if (!confirm("Are you sure you want to reset the day?")) return; - var dayBefore = moment(User.user.lastCron).subtract('days', 1).toDate(); - User.set({'lastCron': dayBefore}); - Notification.text('-1 day, remember to refresh'); - } - $scope.addTenGems = function(){ - $http.post(API_URL + '/api/v2/user/addTenGems').success(function(){ - User.log({}); - }) - } - $scope.addLevelsAndGold = function(){ - User.set({ - 'stats.exp': User.user.stats.exp + 10000, - 'stats.gp': User.user.stats.gp + 10000, - 'stats.mp': User.user.stats.mp + 10000 - }); - } - $scope.addOneLevel = function(){ - User.set({ - 'stats.exp': User.user.stats.exp + (Math.round(((Math.pow(User.user.stats.lvl, 2) * 0.25) + (10 * User.user.stats.lvl) + 139.75) / 10) * 10) - }); + if (window.env.NODE_ENV === 'development') { + $scope.addMissedDay = function(){ + if (!confirm("Are you sure you want to reset the day?")) return; + var dayBefore = moment(User.user.lastCron).subtract('days', 1).toDate(); + User.set({'lastCron': dayBefore}); + Notification.text('-1 day, remember to refresh'); + } + $scope.addTenGems = function(){ + $http.post(API_URL + '/api/v2/user/addTenGems').success(function(){ + User.log({}); + }) + } + $scope.addLevelsAndGold = function(){ + User.set({ + 'stats.exp': User.user.stats.exp + 10000, + 'stats.gp': User.user.stats.gp + 10000, + 'stats.mp': User.user.stats.mp + 10000 + }); + } + $scope.addOneLevel = function(){ + User.set({ + 'stats.exp': User.user.stats.exp + (Math.round(((Math.pow(User.user.stats.lvl, 2) * 0.25) + (10 * User.user.stats.lvl) + 139.75) / 10) * 10) + }); + } } + }]) \ No newline at end of file diff --git a/public/manifest.json b/public/manifest.json index 8784662bac..59fcf38367 100644 --- a/public/manifest.json +++ b/public/manifest.json @@ -81,7 +81,8 @@ "js/static.js", "js/services/notificationServices.js", "bower_components/habitrpg-shared/script/userServices.js", - "js/controllers/authCtrl.js" + "js/controllers/authCtrl.js", + "js/controllers/footerCtrl.js" ], "css": [ "bower_components/bootstrap/dist/css/bootstrap.css", diff --git a/src/controllers/hall.js b/src/controllers/hall.js index 068efdfc3e..0edbd9e867 100644 --- a/src/controllers/hall.js +++ b/src/controllers/hall.js @@ -13,7 +13,7 @@ api.ensureAdmin = function(req, res, next) { } api.getHeroes = function(req,res,next) { - User.find({'contributor.level':{$ne:null}})// {$exists:true} causes terrible performance http://goo.gl/GCxzC9 + User.find({'contributor.level':{$gt:0}}) .select('contributor backer balance profile.name') .sort('-contributor.level') .exec(function(err, users){ diff --git a/src/models/challenge.js b/src/models/challenge.js index 2656bebe1b..a01cea9575 100644 --- a/src/models/challenge.js +++ b/src/models/challenge.js @@ -3,7 +3,6 @@ var Schema = mongoose.Schema; var shared = require('habitrpg-shared'); var _ = require('lodash'); var TaskSchemas = require('./task'); -var Group = require('./group').model; var ChallengeSchema = new Schema({ _id: {type: String, 'default': shared.uuid}, diff --git a/src/models/group.js b/src/models/group.js index fa901dad8f..f3b3cad8e5 100644 --- a/src/models/group.js +++ b/src/models/group.js @@ -3,7 +3,6 @@ var Schema = mongoose.Schema; var shared = require('habitrpg-shared'); var _ = require('lodash'); var async = require('async'); -var User = require('./user').model; var GroupSchema = new Schema({ _id: {type: String, 'default': shared.uuid}, @@ -161,8 +160,6 @@ GroupSchema.methods.finishQuest = function(quest, cb) { }) var members = _.keys(group.quest.members); group.quest = {};group.markModified('quest'); - // FIXME this is TERRIBLE practice. Looks like there are circular dependencies in the models, such that `var User` at - // this point is undefined. So we get around that by loading from mongoose only once we get to this point mongoose.models.User.update({_id:{$in:members}}, updates, {multi:true}, cb); } diff --git a/src/server.js b/src/server.js index aa734c7d3a..04981a8147 100644 --- a/src/server.js +++ b/src/server.js @@ -35,14 +35,18 @@ if (cluster.isMaster && (isDev || isProd)) { // ------------ MongoDB Configuration ------------ mongoose = require('mongoose'); - require('./models/user'); //load up the user schema - TODO is this necessary? - require('./models/group'); - require('./models/challenge'); - mongoose.connect(nconf.get('NODE_DB_URI'), {auto_reconnect:true}, function(err) { - if (err) throw err; - logging.info('Connected with Mongoose'); + var mongooseOptions = !isProd ? {} : { + replset: { socketOptions: { keepAlive: 1, connectTimeoutMS: 30000 } }, + server: { socketOptions: { keepAlive: 1, connectTimeoutMS: 30000 } } + }; + mongoose.connect(nconf.get('NODE_DB_URI'), mongooseOptions, function(err) { + if (err) throw err; + logging.info('Connected with Mongoose'); }); - + // load schemas & models + require('./models/challenge'); + require('./models/group'); + require('./models/user'); // ------------ Passport Configuration ------------ var passport = require('passport') @@ -63,7 +67,6 @@ if (cluster.isMaster && (isDev || isProd)) { done(null, obj); }); - // Use the FacebookStrategy within Passport. // Strategies in Passport require a `verify` function, which accept // credentials (in this case, an accessToken, refreshToken, and Facebook @@ -135,7 +138,7 @@ if (cluster.isMaster && (isDev || isProd)) { app.use('/api/v1', require('./routes/apiv1').middleware); app.use('/export', require('./routes/dataexport').middleware); - app.use(utils.crashWorker(server)); + app.use(utils.crashWorker(server,mongoose)); app.use(utils.errorHandler); require('./routes/apiv2.coffee')(swagger, v2); diff --git a/src/utils.js b/src/utils.js index 4ff8f2a895..1fb45587af 100644 --- a/src/utils.js +++ b/src/utils.js @@ -6,10 +6,10 @@ var cluster = require("cluster"); module.exports.sendEmail = function(mailData) { var smtpTransport = nodemailer.createTransport("SMTP",{ - service: nconf.get('SMTP_SERVICE'), + service: nconf.get('SMTP_SERVICE'), auth: { - user: nconf.get('SMTP_USER'), - pass: nconf.get('SMTP_PASS') + user: nconf.get('SMTP_USER'), + pass: nconf.get('SMTP_PASS') } }); smtpTransport.sendMail(mailData, function(error, response){ @@ -33,8 +33,6 @@ module.exports.makeSalt = function() { return crypto.randomBytes(Math.ceil(len / 2)).toString('hex').substring(0, len); } - - /** * Load nconf and define default configuration values if config.json or ENV vars are not found */ @@ -44,25 +42,13 @@ module.exports.setupConfig = function(){ //.file('defaults', path.join(path.resolve(__dirname, '../config.json.example'))) .file('user', path.join(path.resolve(__dirname, '../config.json'))); -// var agent; -// if (process.env.NODE_ENV === 'development') { -// // Follow these instructions for profiling / debugging leaks -// // * https://developers.google.com/chrome-developer-tools/docs/heap-profiling -// // * https://developers.google.com/chrome-developer-tools/docs/memory-analysis-101 -// agent = require('webkit-devtools-agent'); -// var logging = require('./logging'); -// logging.info("To debug memory leaks:" + -// "\n\t(1) Run `kill -SIGUSR2 " + process.pid + "`" + -// "\n\t(2) open http://c4milo.github.com/node-webkit-agent/21.0.1180.57/inspector.html?host=localhost:1337&page=0"); -// } - - if (nconf.get('NODE_ENV') === "development") { + if (nconf.get('NODE_ENV') === "development") Error.stackTraceLimit = Infinity; - } - if (nconf.get('NODE_ENV') === 'production') require('newrelic'); + if (nconf.get('NODE_ENV') === 'production') + require('newrelic'); }; -module.exports.crashWorker = function(server) { +module.exports.crashWorker = function(server,mongoose) { return function(err, req, res, next) { if (!cluster.isMaster) { // make sure we close down within 30 seconds @@ -73,6 +59,7 @@ module.exports.crashWorker = function(server) { killtimer.unref(); // stop taking new requests. server.close(); + mongoose.connection.close(); cluster.worker.disconnect(); } next(err); diff --git a/views/shared/modals/members.jade b/views/shared/modals/members.jade index 822a59b553..964776aaad 100644 --- a/views/shared/modals/members.jade +++ b/views/shared/modals/members.jade @@ -15,11 +15,11 @@ script(type='text/ng-template', id='modals/member.html') li(ng-show='profile.auth.timestamps.loggedin')=env.t('lastLoggedIn') | {{timestamp(profile.auth.timestamps.loggedin)}} - h3=env.t('stats') - .label.label-info {{ {warrior:'Warrior',wizard:'Mage',healer:'Healer',rogue:'Rogue'}[user.stats.class] }} + .label.label-info {{ {warrior:'Warrior',wizard:'Mage',healer:'Healer',rogue:'Rogue'}[profile.stats.class] }} include ../profiles/stats .span6 include ../header/avatar h3 Achievements include ../profiles/achievements .modal-footer - button.btn.btn-default(ng-click='$close()')=env.t('ok') + button.btn.btn-default(ng-click='$close()')=env.t('ok') \ No newline at end of file diff --git a/views/static/api.jade b/views/static/api.jade index 16b55d8277..276f3bee20 100644 --- a/views/static/api.jade +++ b/views/static/api.jade @@ -16,7 +16,7 @@ html script(src='/bower_components/swagger-ui/dist/lib/swagger.js', type='text/javascript') script(src='/bower_components/swagger-ui/dist/swagger-ui.js', type='text/javascript') script(src='/bower_components/swagger-ui/dist/lib/highlight.7.3.pack.js', type='text/javascript') - script(type='text/javascript') + script(type='text/javascript'). $(function () { window.swaggerUi = new SwaggerUi({ url: "/api/v2/api-docs", diff --git a/views/static/layout.jade b/views/static/layout.jade index f6b943283b..7a6e15c631 100644 --- a/views/static/layout.jade +++ b/views/static/layout.jade @@ -1,12 +1,15 @@ //Trick needed to pass 'env' to ./layout block vars doctype 5 -html +html(ng-app='habitrpgStatic') head block title title=env.t('titleIndex') + script(type='text/javascript'). + window.env = !{JSON.stringify(env)}; + link(rel='shortcut icon', href='#{env.getBuildUrl("favicon.ico")}?v=3') meta(charset='utf-8') @@ -20,7 +23,7 @@ html != env.getManifestFiles("static") body - div(ng-app='habitrpgStatic',ng-controller='AuthCtrl',style='margin-top:60px;') + div(ng-controller='AuthCtrl',style='margin-top:60px;') include ./login-modal nav.navbar.navbar-inverse.navbar-fixed-top .navbar-header