diff --git a/app/core/social-handlers/GPlusHandler.coffee b/app/core/social-handlers/GPlusHandler.coffee index 803f12cbc..ca40485d0 100644 --- a/app/core/social-handlers/GPlusHandler.coffee +++ b/app/core/social-handlers/GPlusHandler.coffee @@ -19,7 +19,7 @@ scope = 'https://www.googleapis.com/auth/plus.login email' module.exports = GPlusHandler = class GPlusHandler extends CocoClass constructor: -> - @accessToken = storage.load GPLUS_TOKEN_KEY + @accessToken = storage.load GPLUS_TOKEN_KEY, false super() subscriptions: @@ -53,7 +53,7 @@ module.exports = GPlusHandler = class GPlusHandler extends CocoClass try # Without removing this, we sometimes get a cross-domain error d = _.omit(e, 'g-oauth-window') - storage.save(GPLUS_TOKEN_KEY, d) + storage.save(GPLUS_TOKEN_KEY, d, 0) catch e console.error 'Unable to save G+ token key', e @accessToken = e diff --git a/app/lib/Angel.coffee b/app/lib/Angel.coffee index 7a1fd118f..f4d4cd22d 100644 --- a/app/lib/Angel.coffee +++ b/app/lib/Angel.coffee @@ -16,6 +16,7 @@ module.exports = class Angel extends CocoClass subscriptions: 'level:flag-updated': 'onFlagEvent' 'playback:stop-real-time-playback': 'onStopRealTimePlayback' + 'level:escape-pressed': 'onEscapePressed' constructor: (@shared) -> super() @@ -165,10 +166,11 @@ module.exports = class Angel extends CocoClass @worker.postMessage func: 'finalizePreload' @work.preload = false - infinitelyLooped: => + infinitelyLooped: (escaped=false) => @say 'On infinitely looped! Aborting?', @aborting return if @aborting problem = type: 'runtime', level: 'error', id: 'runtime_InfiniteLoop', message: 'Code never finished. It\'s either really slow or has an infinite loop.' + problem.message = 'Escape pressed; code aborted.' if escaped Backbone.Mediator.publish 'god:user-code-problem', problem: problem Backbone.Mediator.publish 'god:infinite-loop', firstWorld: @shared.firstWorld @fireWorker() @@ -239,8 +241,14 @@ module.exports = class Angel extends CocoClass onStopRealTimePlayback: (e) -> return unless @running and @work.realTime @work.realTime = false + @lastRealTimeWork = new Date() @worker.postMessage func: 'stopRealTimePlayback' + onEscapePressed: (e) -> + return unless @running and not @work.realTime + return if (new Date() - @lastRealTimeWork) < 1000 # Fires right after onStopRealTimePlayback + @infinitelyLooped true + #### Synchronous code for running worlds on main thread (profiling / IE9) #### simulateSync: (work) => console?.profile? "World Generation #{(Math.random() * 1000).toFixed(0)}" if imitateIE9? diff --git a/app/lib/world/names.coffee b/app/lib/world/names.coffee index ca46eacc7..fca3ffd93 100644 --- a/app/lib/world/names.coffee +++ b/app/lib/world/names.coffee @@ -1,6 +1,7 @@ module.exports.thangNames = thangNames = 'Ogre Munchkin F': [ # Female + 'Anabel' 'Dosha' 'Gurzunn' 'Hoot' @@ -8,6 +9,7 @@ module.exports.thangNames = thangNames = 'Iyert' 'Lacos' 'Palt' + 'Paulark' 'Pripp' 'Shmeal' 'Upfish' @@ -19,9 +21,11 @@ module.exports.thangNames = thangNames = 'Brack' 'Dobo' 'Draff' + 'Eugen' 'Gert' 'Godel' 'Goreball' + 'Toremon' 'Gort' 'Kog' 'Kogpole' diff --git a/app/locale/en.coffee b/app/locale/en.coffee index 3a9d6dea1..a57c3441e 100644 --- a/app/locale/en.coffee +++ b/app/locale/en.coffee @@ -261,6 +261,7 @@ victory_hour_of_code_done_yes: "Yes, I'm finished with my Hour of Code™!" victory_experience_gained: "XP Gained" victory_gems_gained: "Gems Gained" + victory_new_item: "New Item" victory_viking_code_school: "Holy smokes, that was a hard level you just beat! If you aren't already a software developer, you should be. You just got fast-tracked for acceptance with Viking Code School, where you can take your skills to the next level and become a professional web developer in 14 weeks." victory_become_a_viking: "Become a Viking" guide_title: "Guide" diff --git a/app/locale/ru.coffee b/app/locale/ru.coffee index cf797edf1..733882d3a 100644 --- a/app/locale/ru.coffee +++ b/app/locale/ru.coffee @@ -261,6 +261,7 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi victory_hour_of_code_done_yes: "Да, я закончил мой Час Кода™!" victory_experience_gained: "Опыта получено" victory_gems_gained: "Самоцветов получено" + victory_new_item: "Новый предмет" victory_viking_code_school: "Ого, это было тяжелый уровень! Если вы еще не разработчик программ, вам стоит им стать. Вы только что ускорири принятие в Школу Викингов, где вы сможете поднять свои навыки на новый уровень и стать профессиональным веб-разработчиком за 14 недель." victory_become_a_viking: "Станьте Викингом" guide_title: "Руководство" @@ -528,8 +529,6 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi volume_label: "Громкость" music_label: "Музыка" music_description: "Фоновая музыка вкл/выкл" - autorun_label: "Автозапуск" - autorun_description: "Настройка автоматического выполнения кода." editor_config: "Настройки редактора" editor_config_title: "Настройки редактора" editor_config_level_language_label: "Язык для этого уровня" @@ -570,7 +569,7 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi nick_blurb: "Гуру мотивации" michael_title: "Программист" michael_blurb: "Сисадмин" - matt_title: "Программист" + matt_title: "Сооснователь" matt_blurb: "Велосипедист" cat_title: "Главный ремесленник" cat_blurb: "Повелитель стихий" @@ -605,8 +604,8 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi material_title: "Как много здесь материала?" material_china: "Около 22 часов игрового процесса, распределенного более чем на 120 уровней для подписчиков с добавлением 5 уровней каждую неделю." material_1: "Около 8 часов бесплатного контента и 14 часов дополнительного контента для подписчиков с добавлением 5 уровней каждую неделю." - concepts_title: "О каких концептах мы рассказываем? What concepts are covered?" - how_much_title: "How much does a monthly subscription cost?" + concepts_title: "О каких концептах мы рассказываем?" + how_much_title: "Сколько стоит месячная подписка?" how_much_1: "Цена" how_much_2: "месячной подписки" how_much_3: "- $9.99. Подписка может быть отменена в любой момент." diff --git a/app/locale/sk.coffee b/app/locale/sk.coffee index a2e43ae80..bb40e7ef9 100644 --- a/app/locale/sk.coffee +++ b/app/locale/sk.coffee @@ -42,8 +42,8 @@ module.exports = nativeDescription: "slovenčina", englishDescription: "Slovak", diplomat_suggestion: title: "Pomôžte preložiť CodeCombat!" # This shows up when a player switches to a non-English language using the language selector. sub_heading: "Potrebujeme tvoje jazykové zručnosti." - pitch_body: "We develop CodeCombat in English, but we already have players all over the world. Many of them want to play in Slovak but don't speak English, so if you can speak both, please consider signing up to be a Diplomat and help translate both the CodeCombat website and all the levels into Slovak." - missing_translations: "Until we can translate everything into Slovak, you'll see English when Slovak isn't available." + #pitch_body: "We develop CodeCombat in English, but we already have players all over the world. Many of them want to play in Slovak but don't speak English, so if you can speak both, please consider signing up to be a Diplomat and help translate both the CodeCombat website and all the levels into Slovak." + #missing_translations: "Until we can translate everything into Slovak, you'll see English when Slovak isn't available." learn_more: "Zisti viac, ako byť Diplomat" subscribe_as_diplomat: "Prihlásiť sa ako Diplomat" diff --git a/app/locale/zh-HANS.coffee b/app/locale/zh-HANS.coffee index 45ad22f20..276aa9c6d 100644 --- a/app/locale/zh-HANS.coffee +++ b/app/locale/zh-HANS.coffee @@ -64,7 +64,7 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese achievements: "成就" # Tooltip on achievement list button from /play account: "账户" # Tooltip on account button from /play settings: "设置" # Tooltip on settings button from /play -# poll: "Poll" # Tooltip on poll button from /play + poll: "投票" # Tooltip on poll button from /play next: "下一步" # Go from choose hero to choose inventory before playing a level change_hero: "重新选择英雄" # Go back from choose inventory to choose hero choose_inventory: "装备道具" @@ -261,8 +261,9 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese victory_hour_of_code_done_yes: "是的, 完成了!" victory_experience_gained: "获得经验" victory_gems_gained: "获得宝石" -# victory_viking_code_school: "Holy smokes, that was a hard level you just beat! If you aren't already a software developer, you should be. You just got fast-tracked for acceptance with Viking Code School, where you can take your skills to the next level and become a professional web developer in 14 weeks." -# victory_become_a_viking: "Become a Viking" + victory_new_item: "新的物品" + victory_viking_code_school: "这关真的超难! 如果你想成为一个软件开发人员,你就应该去试一下Viking Code School。在这里你可以把你的知识增长到另一个台阶。只需要14周你就能成为一个专业的网页开发人员。" + victory_become_a_viking: "成为一个维京人吧" guide_title: "指南" tome_minion_spells: "助手的咒语" # Only in old-style levels. tome_read_only_spells: "只读的咒语" # Only in old-style levels. @@ -429,15 +430,15 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese # parents_blurb1a: "Computer programming is an essential skill that your child will undoubtedly use as an adult. By 2020, basic software skills will be needed by 77% of jobs, and software engineers are in high demand across the world. Did you know that Computer Science is the highest-paid university degree?" parents_blurb2: "每月支付9.9美元,他们每周都会有新的挑战,并且通过电子邮件获得专业程序员的指导。" # {change} parents_blurb3: "无风险承诺:100%退款,一键退款。" -# payment_methods: "Payment Methods" + payment_methods: "付费方式" # payment_methods_title: "Accepted Payment Methods" -# payment_methods_blurb1: "We currently accept credit cards and Alipay." -# payment_methods_blurb2: "If you require an alternate form of payment, please contact" + payment_methods_blurb1: "我们现有的付费方式有信用卡和支付宝" + payment_methods_blurb2: "如果你想用其他付费方式,请联系我们" stripe_description: "每月订阅" subscription_required_to_play: "订阅后才可开始本关" unlock_help_videos: "订阅后才可以解锁视频教学哦!" # personal_sub: "Personal Subscription" # Accounts Subscription View below -# loading_info: "Loading subscription information..." + loading_info: "正在读入订阅内容..." # managed_by: "Managed by" # will_be_cancelled: "Will be cancelled on" # currently_free: "You currently have a free subscription" @@ -491,7 +492,7 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese skills: "技能" # attack_1: "Deals" # attack_2: "of listed" -# attack_3: "weapon damage." + attack_3: "武器攻击力." # health_1: "Gains" # health_2: "of listed" # health_3: "armor health." @@ -572,11 +573,11 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese michael_blurb: "系统管理员" matt_title: "程序员" matt_blurb: "自行车爱好者" -# cat_title: "Chief Artisan" + cat_title: "首席关卡设计师" # cat_blurb: "Airbender" -# josh_title: "Game Designer" -# josh_blurb: "Floor Is Lava" -# jose_title: "Music" + josh_title: "游戏设计师" + josh_blurb: "地面是熔岩" + jose_title: "音乐" # jose_blurb: "Taking Off" # retrostyle_title: "Illustration" # retrostyle_blurb: "RetroStyle Games" @@ -946,7 +947,7 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese fight: "战斗!" watch_victory: "观看你的胜利" defeat_the: "击败了" -# tournament_started: ", started" + tournament_started: ",锦标赛已开始" tournament_ends: "锦标赛结束" tournament_ended: "Tournament ended" tournament_rules: "锦标赛规则" diff --git a/app/styles/play/level/modal/hero-victory-modal.sass b/app/styles/play/level/modal/hero-victory-modal.sass index f122eaad2..4b6d38247 100644 --- a/app/styles/play/level/modal/hero-victory-modal.sass +++ b/app/styles/play/level/modal/hero-victory-modal.sass @@ -253,6 +253,15 @@ font-weight: bold color: rgb(40, 33, 22) margin-right: 12px + width: 78px + + &.four-digits + font-size: 40px + margin-top: 3px + + &.five-digits + font-size: 30px + margin-top: 10px .total-label float: left diff --git a/app/templates/play/level/modal/hero-victory-modal.jade b/app/templates/play/level/modal/hero-victory-modal.jade index 531aaede2..9b69caf46 100644 --- a/app/templates/play/level/modal/hero-victory-modal.jade +++ b/app/templates/play/level/modal/hero-victory-modal.jade @@ -47,7 +47,10 @@ block modal-body-content .reward-panel.item(data-item-thang-type=item.get('original')) .reward-image-container(class=animate ? 'pending-reward-image' : 'show') img(src=item.getPortraitURL()) - .reward-text= animate ? 'New Item' : item.get('name') + if animate + .reward-text(data-i18n="play_level.victory_new_item") New Item + else + .reward-text= i18n(item.attributes, 'name') block modal-footer-content #totals diff --git a/app/views/play/level/modal/HeroVictoryModal.coffee b/app/views/play/level/modal/HeroVictoryModal.coffee index 61381823b..c5a644044 100644 --- a/app/views/play/level/modal/HeroVictoryModal.coffee +++ b/app/views/play/level/modal/HeroVictoryModal.coffee @@ -68,7 +68,7 @@ module.exports = class HeroVictoryModal extends ModalView for thangTypeOriginal in thangTypeOriginals thangType = new ThangType() thangType.url = "/db/thang.type/#{thangTypeOriginal}/version" - thangType.project = ['original', 'rasterIcon', 'name', 'soundTriggers'] + thangType.project = ['original', 'rasterIcon', 'name', 'soundTriggers', 'i18n'] @thangTypes[thangTypeOriginal] = @supermodel.loadModel(thangType, 'thang').model @newEarnedAchievements = [] @@ -134,6 +134,7 @@ module.exports = class HeroVictoryModal extends ModalView c.me = me c.readyToRank = @level.get('type', true) is 'hero-ladder' and @session.readyToRank() c.level = @level + c.i18n = utils.i18n elapsed = (new Date() - new Date(me.get('dateCreated'))) isHourOfCode = me.get('hourOfCode') or elapsed < 120 * 60 * 1000 @@ -229,6 +230,8 @@ module.exports = class HeroVictoryModal extends ModalView @updateXPBars(totalXP) xpTrigger = 'xp-' + (totalXP % 6) # 6 xp sounds Backbone.Mediator.publish 'audio-player:play-sound', trigger: xpTrigger, volume: 0.5 + ratio / 2 + @XPEl.addClass 'four-digits' if totalXP >= 1000 and @lastTotalXP < 1000 + @XPEl.addClass 'five-digits' if totalXP >= 10000 and @lastTotalXP < 10000 @lastTotalXP = totalXP else if panel.unit is 'gem' newGems = Math.floor(panel.previousNumber + ratio * (panel.number - panel.previousNumber)) @@ -238,10 +241,12 @@ module.exports = class HeroVictoryModal extends ModalView @gemEl.text(totalGems) gemTrigger = 'gem-' + (parseInt(panel.number * ratio) % 4) # 4 gem sounds Backbone.Mediator.publish 'audio-player:play-sound', trigger: gemTrigger, volume: 0.5 + ratio / 2 + @gemEl.addClass 'four-digits' if totalGems >= 1000 and @lastTotalGems < 1000 + @gemEl.addClass 'five-digits' if totalGems >= 10000 and @lastTotalGems < 10000 @lastTotalGems = totalGems else if panel.item thangType = @thangTypes[panel.item] - panel.textEl.text(thangType.get('name')) + panel.textEl.text utils.i18n(thangType.attributes, 'name') Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'item-unlocked', volume: 1 if 0.5 < ratio < 0.6 else if panel.hero thangType = @thangTypes[panel.hero] diff --git a/app/views/play/level/tome/SpellView.coffee b/app/views/play/level/tome/SpellView.coffee index 5d13a8094..cb4a13db5 100644 --- a/app/views/play/level/tome/SpellView.coffee +++ b/app/views/play/level/tome/SpellView.coffee @@ -153,7 +153,6 @@ module.exports = class SpellView extends CocoView bindKey: {win: 'Escape', mac: 'Escape'} readOnly: true exec: -> - console.log 'esc pressed' Backbone.Mediator.publish 'level:escape-pressed', {} addCommand name: 'toggle-grid' diff --git a/bin/coco-mongodb b/bin/coco-mongodb index d6aafe9cc..e9e3d78f3 100755 --- a/bin/coco-mongodb +++ b/bin/coco-mongodb @@ -71,7 +71,7 @@ def which(cmd, mode=os.F_OK | os.X_OK, path=None): current_directory = os.path.dirname(os.path.realpath(sys.argv[0])) -allowedMongoVersions = ["v2.6"] +allowedMongoVersions = ["v2.6", "v3.0"] if which("mongod") and any(i in subprocess.check_output("mongod --version",shell=True) for i in allowedMongoVersions): mongo_executable = "mongod" else: diff --git a/headless_client.coffee b/headless_client.coffee index 0fd94de10..e2f0f0b33 100644 --- a/headless_client.coffee +++ b/headless_client.coffee @@ -3,7 +3,7 @@ This file will simulate games on node.js by emulating the browser environment. In order to use, followed these steps: 1. Setup dev environment as usual 2. Create a `login.coffee` file in coco which contains: -module.exports = username: 'email@example.com', password: 'password' +module.exports = username: 'email@example.com', password: 'your_password' 3. Run `./node_modules/coffee-script/bin/coffee ./headless_client.coffee` Alternatively, if you wish only to simulate a single game run `coffee ./headless_client.coffee one-game` Or, if you want to always simulate only one game, change the line below this to "true". This takes way more bandwidth. diff --git a/multicore.coffee b/multicore.coffee index 2a78205d7..2ce343d55 100644 --- a/multicore.coffee +++ b/multicore.coffee @@ -1,11 +1,79 @@ cluster = require 'cluster' numCPUs = require('os').cpus().length +deaths = [ + 'Killed by a soldier ant.' + 'Ascended.' + 'Killed by an invisible gnome lord.' + 'Died of starvation.' + 'Petrified by a cockatrice corpse.' + 'Poisoned by a rotted kobold corpse.' + 'Fell into a pit.' + 'Killed by brainlessness.' + 'Slipped while mounting a saddled pony called Rainbow Dash.' + 'Killed by a scroll of genocide.' + 'Choked on a tin of spinach.' + 'Killed by the wrath of Anhur.' + 'Killed by a jackal, while fainted from lack of food.' + 'Drowned in a pool of water by an electric eel.' + 'Killed by falling downstairs.' + 'Killed by an ape, while helpless.' + 'Burned by a tower of flame.' + 'Killed by Ms. Sipaliwini, the shopkeeper.' + 'Fell onto a sink.' + 'Killed by a killer bee, while praying.' + 'Crushed to death by a collapsing drawbridge.' + 'Crunched in the head by an iron ball.' + 'Killed by exhaustion.' + 'Caught itself in its own magical blast.' + 'Shot itself with a death ray.' + 'Killed by genocidal confusion.' + 'Killed by touching Excalibur.' + 'Killed by a hallucinogen-distorted dwarf.' + 'Dissolved in molten lava.' + 'Turned to slime by a green slime.' + 'Killed by sipping boiling water.' + 'A trickery.' + 'Escaped (in celestial disgrace)' + 'Killed by kicking a sink.' + 'Killed by a kitten called Steve, while sleeping.' + 'Went to heaven prematurely.' + 'Teleported out of the dungeon and fell to its death.' + 'Panic.' + 'Killed by a minotuar, while dressing up.' + 'Petrified by trying to help a cockatrice out of a pit.' + 'Killed by a luckstone.' + 'Killed by a panther, while taking off clothes.' + 'Killed by a watch captain called The Nymphmaster.' + 'Killed by a black pudding, while jumping around.' + 'Killed by a hallucinogen-distorted white unicorn, while praying.' + 'Choked on a slice of birthday cake.' + 'Killed by a long worm, while reading a book.' + 'Killed by a giant beetle, while vomiting.' + 'Killed by an invisible master mind flayer, while unconscious from rotten food.' + 'Burned by burning.' + 'Killed by an air elemental, while hiding from thunderstorm (with the Amulet).' + 'Killed by wedging into a narrow crevice.' + 'Killed by a carnivorous bag.' + 'Killed by axing a hard object.' + 'Killed by an iron ball collision.' + 'Killed by an alchemic blast.' + 'Killed by dangerous winds.' + 'Killed by psychic blast.' + 'Committed suicide.' + 'Squished under a boulder.' + 'Killed by colliding with the ceiling.' + 'Killed by sitting on an iron spike.' + "Quit while already on Charon's boat." + 'Fell into a chasm.' + 'Turned to slime by a cockatrice egg.' +] + if cluster.isMaster for i in [0...numCPUs] cluster.fork() cluster.on 'exit', (worker, code, signal) -> - message = "Worker #{worker.id} died! Heart attack takin' a dump." + message = "Worker #{worker.id} died! #{deaths[Math.floor Math.random() * deaths.length]}" console.log message try hipchat = require './server/hipchat' diff --git a/scripts/devSetup/mongo.py b/scripts/devSetup/mongo.py index 957e6cf58..a1bd36b78 100644 --- a/scripts/devSetup/mongo.py +++ b/scripts/devSetup/mongo.py @@ -86,10 +86,10 @@ class LinuxMongoDBDownloader(MongoDBDownloader): @property def download_url(self): if self.dependency.config.mem_width == 64: - return u"http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-2.6.6.tgz" + return u"http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.0.2.tgz" else: warnings.warn(u"MongoDB *really* doesn't run well on 32 bit systems. You have been warned.") - return u"http://fastdl.mongodb.org/linux/mongodb-linux-i686-2.6.6.tgz" + return u"http://fastdl.mongodb.org/linux/mongodb-linux-i686-3.0.2.tgz" class WindowsMongoDBDownloader(MongoDBDownloader): @property @@ -97,11 +97,11 @@ class WindowsMongoDBDownloader(MongoDBDownloader): #TODO: Implement Windows Vista detection warnings.warn(u"If you have a version of Windows older than 7, MongoDB may not function properly!") if self.dependency.config.mem_width == 64: - return u"http://fastdl.mongodb.org/win32/mongodb-win32-x86_64-2008plus-2.6.6.zip" + return u"http://fastdl.mongodb.org/win32/mongodb-win32-x86_64-2008plus-3.0.2.zip" else: - return u"http://fastdl.mongodb.org/win32/mongodb-win32-i386-2.6.6.zip" + return u"http://fastdl.mongodb.org/win32/mongodb-win32-i386-3.0.2.zip" class MacMongoDBDownloader(MongoDBDownloader): @property def download_url(self): - return u"http://fastdl.mongodb.org/osx/mongodb-osx-x86_64-2.6.6.tgz" + return u"http://fastdl.mongodb.org/osx/mongodb-osx-x86_64-3.0.2.tgz" diff --git a/scripts/windows/install-mongodb.ps1 b/scripts/windows/install-mongodb.ps1 index e591e064e..abe6cc39f 100755 --- a/scripts/windows/install-mongodb.ps1 +++ b/scripts/windows/install-mongodb.ps1 @@ -2,9 +2,9 @@ Set-ExecutionPolicy RemoteSigned $mongoDbPath = "C:\MongoDB" $mongoDbConfigPath = "$mongoDbPath\mongod.cfg" -$url = "http://downloads.mongodb.org/win32/mongodb-win32-x86_64-2008plus-2.6.4.zip" +$url = "http://downloads.mongodb.org/win32/mongodb-win32-x86_64-2008plus-3.0.2.zip" $zipFile = "$mongoDbPath\mongo.zip" -$unzippedFolderContent ="$mongoDbPath\mongodb-win32-x86_64-2008plus-2.6.4.zip" +$unzippedFolderContent ="$mongoDbPath\mongodb-win32-x86_64-2008plus-3.0.2.zip" if ((Test-Path -path $mongoDbPath) -eq $True) { diff --git a/server/clans/clan_handler.coffee b/server/clans/clan_handler.coffee index 9fdb275f1..a4fe13f99 100644 --- a/server/clans/clan_handler.coffee +++ b/server/clans/clan_handler.coffee @@ -79,7 +79,7 @@ ClanHandler = class ClanHandler extends Handler return @sendNotFoundError(res, err) Clan.findById clanID, (err, clan) => return @sendDatabaseError(res, err) if err - return @sendDatabaseError(res, err) unless clan + return @sendNotFoundError(res) unless clan return @sendForbiddenError(res) if clan.get('ownerID')?.equals req.user._id Clan.update {_id: clanID}, {$pull: {members: req.user._id}}, (err) => return @sendDatabaseError(res, err) if err diff --git a/server/commons/Handler.coffee b/server/commons/Handler.coffee index 844b81e10..a2bcc60ad 100644 --- a/server/commons/Handler.coffee +++ b/server/commons/Handler.coffee @@ -81,7 +81,7 @@ module.exports = class Handler sendBadInputError: (res, message) -> errors.badInput(res, message) sendPaymentRequiredError: (res, message) -> errors.paymentRequired(res, message) sendDatabaseError: (res, err) -> - return @sendError(res, err.code, err.response) if err.response and err.code + return @sendError(res, err.code, err.response) if err?.response and err?.code log.error "Database error, #{err}" errors.serverError(res, 'Database error, ' + err) diff --git a/server/routes/file.coffee b/server/routes/file.coffee index b1085baaf..4c6de3cf0 100644 --- a/server/routes/file.coffee +++ b/server/routes/file.coffee @@ -22,7 +22,7 @@ fileDelete = (req, res) -> Grid.gfs.remove {_id: filedata._id, root: 'media'}, (err) -> return errors.serverError(res) if err return res.end() - + fileGet = (req, res) -> query = parsePathIntoQuery(req.path) @@ -48,7 +48,7 @@ fileGet = (req, res) -> res.setHeader('Cache-Control', 'public') readstream.pipe(res) handleStreamEnd(res, res) - + parsePathIntoQuery = (path) -> path = path[6..] path = decodeURI path @@ -130,7 +130,7 @@ savePNG = (req, res) -> userCanEditFile = (user=null, file=null) -> # no user means 'anyone'. No file means 'any file' return false unless user - return true if user.isAdmin() + return true if user.isAdmin() or user.isArtisan() return false unless file return true if file.metadata.creator is user.id return false diff --git a/server/users/user_handler.coffee b/server/users/user_handler.coffee index 13601fe9c..18c362c7e 100644 --- a/server/users/user_handler.coffee +++ b/server/users/user_handler.coffee @@ -189,7 +189,7 @@ UserHandler = class UserHandler extends Handler leaderboardQuery = User.find(queryParameters.query).select('name simulatedBy simulatedFor').sort({'simulatedBy': queryParameters.sortOrder}).limit(queryParameters.limit) leaderboardQuery.cache() if req.query.scoreOffset is -1 leaderboardQuery.exec (err, otherUsers) -> - otherUsers = _.reject otherUsers, _id: req.user._id if req.query.scoreOffset isnt -1 + otherUsers = _.reject otherUsers, _id: req.user._id if req.query.scoreOffset isnt -1 and req.user otherUsers ?= [] res.send(otherUsers) res.end()