├── .gitignore
├── Procfile
├── README.md
├── api_data
├── champions.json
├── dd_patch.json
├── index.js
├── items.json
├── masteries.json
├── runes.js
├── skills.json
└── summoners.json
├── app.js
├── bash.txt
├── bin
├── update_server.sh
└── www.js
├── config
└── config.js
├── db.js
├── db
└── championgg
│ ├── webchampionpages.bson
│ ├── webchampionpages.metadata.json
│ ├── webchampionroles.bson
│ ├── webchampionroles.metadata.json
│ ├── webhomepagesummaries.bson
│ ├── webhomepagesummaries.metadata.json
│ ├── webmatchuppages.bson
│ ├── webmatchuppages.metadata.json
│ ├── weboverallroledatas.bson
│ ├── weboverallroledatas.metadata.json
│ ├── weboverallstats.bson
│ ├── weboverallstats.metadata.json
│ ├── webstatisticspages.bson
│ └── webstatisticspages.metadata.json
├── gruntfile.js
├── headline.js
├── logic
├── lower_case_champ.js
├── produce_error.js
└── role_hash_table.js
├── middleware
└── overall_data.js
├── models
├── web_champion_page.js
├── web_champion_roles.js
├── web_home_page_summaries.js
├── web_matchup_page.js
├── web_overall_role_data.js
├── web_overall_stats.js
└── web_statistics_page.js
├── package.json
├── public
├── cpmstar
│ └── cpmstar_siteskin_iframebuster.html
├── css
│ ├── master.css
│ ├── master.min.css
│ └── sprite.css
├── dist
│ ├── css
│ │ ├── bootstrap.min.css
│ │ └── jquery-ui.min.css
│ ├── fonts
│ │ ├── glyphicons-halflings-regular.eot
│ │ ├── glyphicons-halflings-regular.svg
│ │ ├── glyphicons-halflings-regular.ttf
│ │ └── glyphicons-halflings-regular.woff
│ └── js
│ │ ├── angular-bootstrap.js
│ │ ├── angular.js
│ │ ├── chart.js
│ │ ├── dirDisqus.js
│ │ └── tc-angular-chartjs.js
├── favicon.ico
├── googled8153283379da1fb.html
├── img
│ ├── bg.jpg
│ ├── champion.jpg
│ ├── header-bg.jpg
│ ├── logo.png
│ ├── mastery0.jpg
│ ├── mastery1.jpg
│ ├── mastery2.jpg
│ └── small_champion.jpg
├── js
│ ├── app.js
│ ├── champion_data.js
│ ├── champion_page.js
│ ├── championgg_tooltip.js
│ ├── chart_options.js
│ ├── master.min.js
│ ├── matchup_page.js
│ ├── statistics_jquery.js
│ └── statistics_page.js
├── opensearchdescription.xml
├── riot.html
└── template
│ └── typeahead
│ └── typeahead-popup.html
├── routes
├── api_static.js
├── champion.js
├── faq.js
├── index.js
├── matchup.js
├── matchup_json.js
└── statistics.js
├── update_data.sh
├── update_server.sh
└── views
├── champion.ejs
├── champion
├── advertisement.ejs
├── champion_image_roles.ejs
├── champion_statistics.ejs
├── core_build.ejs
├── counters_matchups.ejs
├── first_items.ejs
├── gamelength_experience_summoners.ejs
├── masteries.ejs
├── reddit.ejs
├── runes.ejs
├── skill_order.ejs
├── viktor_upgrade.ejs
└── winrate_playrate_damage_advert_trinket.ejs
├── error.ejs
├── faq.ejs
├── footer.ejs
├── header.ejs
├── index.ejs
├── matchup.ejs
├── new_champion.ejs
├── scripts.ejs
└── statistics.ejs
/.gitignore:
--------------------------------------------------------------------------------
1 | ### Node ###
2 | # Logs
3 | logs
4 | *.log
5 |
6 | # Runtime data
7 | pids
8 | *.pid
9 | *.seed
10 |
11 | # Directory for instrumented libs generated by jscoverage/JSCover
12 | lib-cov
13 |
14 | # Coverage directory used by tools like istanbul
15 | coverage
16 |
17 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
18 | .grunt
19 |
20 | # node-waf configuration
21 | .lock-wscript
22 |
23 | # Compiled binary addons (http://nodejs.org/api/addons.html)
24 | build/Release
25 |
26 | # Dependency directory
27 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git-
28 | node_modules
29 |
30 |
31 | ### Intellij ###
32 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
33 |
34 | *.iml
35 |
36 | ## Directory-based project format:
37 | .idea/
38 | # if you remove the above rule, at least ignore the following:
39 |
40 | # User-specific stuff:
41 | # .idea/workspace.xml
42 | # .idea/tasks.xml
43 | # .idea/dictionaries
44 |
45 | # Sensitive or high-churn files:
46 | # .idea/dataSources.ids
47 | # .idea/dataSources.xml
48 | # .idea/sqlDataSources.xml
49 | # .idea/dynamic.xml
50 | # .idea/uiDesigner.xml
51 |
52 | # Gradle:
53 | # .idea/gradle.xml
54 | # .idea/libraries
55 |
56 | # Mongo Explorer plugin:
57 | # .idea/mongoSettings.xml
58 |
59 | ## File-based project format:
60 | *.ipr
61 | *.iws
62 |
63 | ## Plugin-specific files:
64 |
65 | # IntelliJ
66 | out/
67 |
68 | # mpeltonen/sbt-idea plugin
69 | .idea_modules/
70 |
71 | # JIRA plugin
72 | atlassian-ide-plugin.xml
73 |
74 | # Crashlytics plugin (for Android Studio and IntelliJ)
75 | com_crashlytics_export_strings.xml
76 | crashlytics.properties
77 | crashlytics-build.properties
78 |
79 |
80 | ### SublimeText ###
81 | # cache files for sublime text
82 | *.tmlanguage.cache
83 | *.tmPreferences.cache
84 | *.stTheme.cache
85 |
86 | # workspace files are user-specific
87 | *.sublime-workspace
88 |
89 | # project files should be checked into the repository, unless a significant
90 | # proportion of contributors will probably not be using SublimeText
91 | # *.sublime-project
92 |
93 | # sftp configuration file
94 | sftp-config.json
95 |
--------------------------------------------------------------------------------
/Procfile:
--------------------------------------------------------------------------------
1 | worker: node worker.js
2 | web: npm start
3 | clock: node clock.js
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | champion.gg
2 | ========
3 | WEBSITE: http://champion.gg
4 |
5 | A MEAN project (with a dash of angular).
6 | In order to get a local version of champion.gg running you need to have MongoDb, Node and NPM installed. (ensure MongoDB is running when trying to run champion.gg)
7 |
8 | To get a working version set up you'll need to clone the repo, install the dependencies, build the database and then start the server from the command line.
9 | The commands to enter are listed below.
10 |
11 | # Getting set up
12 |
13 | Clone champion.gg:
14 | ```sh
15 | git clone https://github.com/joel1st/championweb.git
16 | ```
17 |
18 | Install dependencies from project directory:
19 | ```sh
20 | npm install
21 | ```
22 |
23 | Restore database from project directory
24 | ```sh
25 | mongorestore --db championgg --collection webchampionpages --drop db/championgg/webchampionpages.bson
26 | mongorestore --db championgg --collection webchampionroles --drop db/championgg/webchampionroles.bson
27 | mongorestore --db championgg --collection webmatchuppages --drop db/championgg/webmatchuppages.bson
28 | mongorestore --db championgg --collection weboverallroledatas --drop db/championgg/weboverallroledatas.bson
29 | mongorestore --db championgg --collection weboverallstats --drop db/championgg/weboverallstats.bson
30 | mongorestore --db championgg --collection webhomepagesummaries --drop db/championgg/webhomepagesummaries.bson
31 | mongorestore --db championgg --collection webstatisticspages --drop db/championgg/webstatisticspages.bson
32 | ```
33 |
34 | Start Champion.gg
35 | ```sh
36 | npm start
37 | #if you have another web server running on port 80 you can set the port as such
38 | PORT=8888 npm start
39 | ```
40 | You can now access champion.gg on http://localhost/ or if you set a port number http://localhost:8888/
41 |
42 | # Development
43 |
44 | In order to work on champion.gg more effectively I've created a grunt tasks to facilitate automation of javascript hinting (helps avoid nasty javascript errors).
45 | ```sh
46 | grunt watch
47 | ```
48 |
49 | To get assets ready for production:
50 | ```sh
51 | grunt production
52 | ```
53 |
--------------------------------------------------------------------------------
/api_data/champions.json:
--------------------------------------------------------------------------------
1 | {"Aatrox":{"id":266,"key":"Aatrox","name":"Aatrox","title":"the Darkin Blade"},"Ahri":{"id":103,"key":"Ahri","name":"Ahri","title":"the Nine-Tailed Fox"},"Akali":{"id":84,"key":"Akali","name":"Akali","title":"the Fist of Shadow"},"Alistar":{"id":12,"key":"Alistar","name":"Alistar","title":"the Minotaur"},"Amumu":{"id":32,"key":"Amumu","name":"Amumu","title":"the Sad Mummy"},"Anivia":{"id":34,"key":"Anivia","name":"Anivia","title":"the Cryophoenix"},"Annie":{"id":1,"key":"Annie","name":"Annie","title":"the Dark Child"},"Ashe":{"id":22,"key":"Ashe","name":"Ashe","title":"the Frost Archer"},"AurelionSol":{"id":136,"key":"AurelionSol","name":"Aurelion Sol","title":"The Star Forger"},"Azir":{"id":268,"key":"Azir","name":"Azir","title":"the Emperor of the Sands"},"Bard":{"id":432,"key":"Bard","name":"Bard","title":"the Wandering Caretaker"},"Blitzcrank":{"id":53,"key":"Blitzcrank","name":"Blitzcrank","title":"the Great Steam Golem"},"Brand":{"id":63,"key":"Brand","name":"Brand","title":"the Burning Vengeance"},"Braum":{"id":201,"key":"Braum","name":"Braum","title":"the Heart of the Freljord"},"Caitlyn":{"id":51,"key":"Caitlyn","name":"Caitlyn","title":"the Sheriff of Piltover"},"Camille":{"id":164,"key":"Camille","name":"Camille","title":"the Steel Shadow"},"Cassiopeia":{"id":69,"key":"Cassiopeia","name":"Cassiopeia","title":"the Serpent's Embrace"},"Chogath":{"id":31,"key":"Chogath","name":"Cho'Gath","title":"the Terror of the Void"},"Corki":{"id":42,"key":"Corki","name":"Corki","title":"the Daring Bombardier"},"Darius":{"id":122,"key":"Darius","name":"Darius","title":"the Hand of Noxus"},"Diana":{"id":131,"key":"Diana","name":"Diana","title":"Scorn of the Moon"},"Draven":{"id":119,"key":"Draven","name":"Draven","title":"the Glorious Executioner"},"DrMundo":{"id":36,"key":"DrMundo","name":"Dr. Mundo","title":"the Madman of Zaun"},"Ekko":{"id":245,"key":"Ekko","name":"Ekko","title":"the Boy Who Shattered Time"},"Elise":{"id":60,"key":"Elise","name":"Elise","title":"the Spider Queen"},"Evelynn":{"id":28,"key":"Evelynn","name":"Evelynn","title":"the Widowmaker"},"Ezreal":{"id":81,"key":"Ezreal","name":"Ezreal","title":"the Prodigal Explorer"},"Fiddlesticks":{"id":9,"key":"Fiddlesticks","name":"Fiddlesticks","title":"the Harbinger of Doom"},"Fiora":{"id":114,"key":"Fiora","name":"Fiora","title":"the Grand Duelist"},"Fizz":{"id":105,"key":"Fizz","name":"Fizz","title":"the Tidal Trickster"},"Galio":{"id":3,"key":"Galio","name":"Galio","title":"the Colossus"},"Gangplank":{"id":41,"key":"Gangplank","name":"Gangplank","title":"the Saltwater Scourge"},"Garen":{"id":86,"key":"Garen","name":"Garen","title":"The Might of Demacia"},"Gnar":{"id":150,"key":"Gnar","name":"Gnar","title":"the Missing Link"},"Gragas":{"id":79,"key":"Gragas","name":"Gragas","title":"the Rabble Rouser"},"Graves":{"id":104,"key":"Graves","name":"Graves","title":"the Outlaw"},"Hecarim":{"id":120,"key":"Hecarim","name":"Hecarim","title":"the Shadow of War"},"Heimerdinger":{"id":74,"key":"Heimerdinger","name":"Heimerdinger","title":"the Revered Inventor"},"Illaoi":{"id":420,"key":"Illaoi","name":"Illaoi","title":"the Kraken Priestess"},"Irelia":{"id":39,"key":"Irelia","name":"Irelia","title":"the Will of the Blades"},"Ivern":{"id":427,"key":"Ivern","name":"Ivern","title":"the Green Father"},"Janna":{"id":40,"key":"Janna","name":"Janna","title":"the Storm's Fury"},"JarvanIV":{"id":59,"key":"JarvanIV","name":"Jarvan IV","title":"the Exemplar of Demacia"},"Jax":{"id":24,"key":"Jax","name":"Jax","title":"Grandmaster at Arms"},"Jayce":{"id":126,"key":"Jayce","name":"Jayce","title":"the Defender of Tomorrow"},"Jhin":{"id":202,"key":"Jhin","name":"Jhin","title":"the Virtuoso"},"Jinx":{"id":222,"key":"Jinx","name":"Jinx","title":"the Loose Cannon"},"Kalista":{"id":429,"key":"Kalista","name":"Kalista","title":"the Spear of Vengeance"},"Karma":{"id":43,"key":"Karma","name":"Karma","title":"the Enlightened One"},"Karthus":{"id":30,"key":"Karthus","name":"Karthus","title":"the Deathsinger"},"Kassadin":{"id":38,"key":"Kassadin","name":"Kassadin","title":"the Void Walker"},"Katarina":{"id":55,"key":"Katarina","name":"Katarina","title":"the Sinister Blade"},"Kayle":{"id":10,"key":"Kayle","name":"Kayle","title":"The Judicator"},"Kennen":{"id":85,"key":"Kennen","name":"Kennen","title":"the Heart of the Tempest"},"Khazix":{"id":121,"key":"Khazix","name":"Kha'Zix","title":"the Voidreaver"},"Kindred":{"id":203,"key":"Kindred","name":"Kindred","title":"The Eternal Hunters"},"Kled":{"id":240,"key":"Kled","name":"Kled","title":"the Cantankerous Cavalier"},"KogMaw":{"id":96,"key":"KogMaw","name":"Kog'Maw","title":"the Mouth of the Abyss"},"Leblanc":{"id":7,"key":"Leblanc","name":"LeBlanc","title":"the Deceiver"},"LeeSin":{"id":64,"key":"LeeSin","name":"Lee Sin","title":"the Blind Monk"},"Leona":{"id":89,"key":"Leona","name":"Leona","title":"the Radiant Dawn"},"Lissandra":{"id":127,"key":"Lissandra","name":"Lissandra","title":"the Ice Witch"},"Lucian":{"id":236,"key":"Lucian","name":"Lucian","title":"the Purifier"},"Lulu":{"id":117,"key":"Lulu","name":"Lulu","title":"the Fae Sorceress"},"Lux":{"id":99,"key":"Lux","name":"Lux","title":"the Lady of Luminosity"},"Malphite":{"id":54,"key":"Malphite","name":"Malphite","title":"Shard of the Monolith"},"Malzahar":{"id":90,"key":"Malzahar","name":"Malzahar","title":"the Prophet of the Void"},"Maokai":{"id":57,"key":"Maokai","name":"Maokai","title":"the Twisted Treant"},"MasterYi":{"id":11,"key":"MasterYi","name":"Master Yi","title":"the Wuju Bladesman"},"MissFortune":{"id":21,"key":"MissFortune","name":"Miss Fortune","title":"the Bounty Hunter"},"MonkeyKing":{"id":62,"key":"MonkeyKing","name":"Wukong","title":"the Monkey King"},"Mordekaiser":{"id":82,"key":"Mordekaiser","name":"Mordekaiser","title":"the Iron Revenant"},"Morgana":{"id":25,"key":"Morgana","name":"Morgana","title":"Fallen Angel"},"Nami":{"id":267,"key":"Nami","name":"Nami","title":"the Tidecaller"},"Nasus":{"id":75,"key":"Nasus","name":"Nasus","title":"the Curator of the Sands"},"Nautilus":{"id":111,"key":"Nautilus","name":"Nautilus","title":"the Titan of the Depths"},"Nidalee":{"id":76,"key":"Nidalee","name":"Nidalee","title":"the Bestial Huntress"},"Nocturne":{"id":56,"key":"Nocturne","name":"Nocturne","title":"the Eternal Nightmare"},"Nunu":{"id":20,"key":"Nunu","name":"Nunu","title":"the Yeti Rider"},"Olaf":{"id":2,"key":"Olaf","name":"Olaf","title":"the Berserker"},"Orianna":{"id":61,"key":"Orianna","name":"Orianna","title":"the Lady of Clockwork"},"Pantheon":{"id":80,"key":"Pantheon","name":"Pantheon","title":"the Artisan of War"},"Poppy":{"id":78,"key":"Poppy","name":"Poppy","title":"Keeper of the Hammer"},"Quinn":{"id":133,"key":"Quinn","name":"Quinn","title":"Demacia's Wings"},"Rakan":{"id":497,"key":"Rakan","name":"Rakan","title":"The Charmer"},"Rammus":{"id":33,"key":"Rammus","name":"Rammus","title":"the Armordillo"},"RekSai":{"id":421,"key":"RekSai","name":"Rek'Sai","title":"the Void Burrower"},"Renekton":{"id":58,"key":"Renekton","name":"Renekton","title":"the Butcher of the Sands"},"Rengar":{"id":107,"key":"Rengar","name":"Rengar","title":"the Pridestalker"},"Riven":{"id":92,"key":"Riven","name":"Riven","title":"the Exile"},"Rumble":{"id":68,"key":"Rumble","name":"Rumble","title":"the Mechanized Menace"},"Ryze":{"id":13,"key":"Ryze","name":"Ryze","title":"the Rune Mage"},"Sejuani":{"id":113,"key":"Sejuani","name":"Sejuani","title":"Fury of the North"},"Shaco":{"id":35,"key":"Shaco","name":"Shaco","title":"the Demon Jester"},"Shen":{"id":98,"key":"Shen","name":"Shen","title":"the Eye of Twilight"},"Shyvana":{"id":102,"key":"Shyvana","name":"Shyvana","title":"the Half-Dragon"},"Singed":{"id":27,"key":"Singed","name":"Singed","title":"the Mad Chemist"},"Sion":{"id":14,"key":"Sion","name":"Sion","title":"The Undead Juggernaut"},"Sivir":{"id":15,"key":"Sivir","name":"Sivir","title":"the Battle Mistress"},"Skarner":{"id":72,"key":"Skarner","name":"Skarner","title":"the Crystal Vanguard"},"Sona":{"id":37,"key":"Sona","name":"Sona","title":"Maven of the Strings"},"Soraka":{"id":16,"key":"Soraka","name":"Soraka","title":"the Starchild"},"Swain":{"id":50,"key":"Swain","name":"Swain","title":"the Master Tactician"},"Syndra":{"id":134,"key":"Syndra","name":"Syndra","title":"the Dark Sovereign"},"TahmKench":{"id":223,"key":"TahmKench","name":"Tahm Kench","title":"the River King"},"Taliyah":{"id":163,"key":"Taliyah","name":"Taliyah","title":"the Stoneweaver"},"Talon":{"id":91,"key":"Talon","name":"Talon","title":"the Blade's Shadow"},"Taric":{"id":44,"key":"Taric","name":"Taric","title":"the Shield of Valoran"},"Teemo":{"id":17,"key":"Teemo","name":"Teemo","title":"the Swift Scout"},"Thresh":{"id":412,"key":"Thresh","name":"Thresh","title":"the Chain Warden"},"Tristana":{"id":18,"key":"Tristana","name":"Tristana","title":"the Yordle Gunner"},"Trundle":{"id":48,"key":"Trundle","name":"Trundle","title":"the Troll King"},"Tryndamere":{"id":23,"key":"Tryndamere","name":"Tryndamere","title":"the Barbarian King"},"TwistedFate":{"id":4,"key":"TwistedFate","name":"Twisted Fate","title":"the Card Master"},"Twitch":{"id":29,"key":"Twitch","name":"Twitch","title":"the Plague Rat"},"Udyr":{"id":77,"key":"Udyr","name":"Udyr","title":"the Spirit Walker"},"Urgot":{"id":6,"key":"Urgot","name":"Urgot","title":"the Headsman's Pride"},"Varus":{"id":110,"key":"Varus","name":"Varus","title":"the Arrow of Retribution"},"Vayne":{"id":67,"key":"Vayne","name":"Vayne","title":"the Night Hunter"},"Veigar":{"id":45,"key":"Veigar","name":"Veigar","title":"the Tiny Master of Evil"},"Velkoz":{"id":161,"key":"Velkoz","name":"Vel'Koz","title":"the Eye of the Void"},"Vi":{"id":254,"key":"Vi","name":"Vi","title":"the Piltover Enforcer"},"Viktor":{"id":112,"key":"Viktor","name":"Viktor","title":"the Machine Herald"},"Vladimir":{"id":8,"key":"Vladimir","name":"Vladimir","title":"the Crimson Reaper"},"Volibear":{"id":106,"key":"Volibear","name":"Volibear","title":"the Thunder's Roar"},"Warwick":{"id":19,"key":"Warwick","name":"Warwick","title":"the Uncaged Wrath of Zaun"},"Xayah":{"id":498,"key":"Xayah","name":"Xayah","title":"the Rebel"},"Xerath":{"id":101,"key":"Xerath","name":"Xerath","title":"the Magus Ascendant"},"XinZhao":{"id":5,"key":"XinZhao","name":"Xin Zhao","title":"the Seneschal of Demacia"},"Yasuo":{"id":157,"key":"Yasuo","name":"Yasuo","title":"the Unforgiven"},"Yorick":{"id":83,"key":"Yorick","name":"Yorick","title":"Shepherd of Souls"},"Zac":{"id":154,"key":"Zac","name":"Zac","title":"the Secret Weapon"},"Zed":{"id":238,"key":"Zed","name":"Zed","title":"the Master of Shadows"},"Ziggs":{"id":115,"key":"Ziggs","name":"Ziggs","title":"the Hexplosives Expert"},"Zilean":{"id":26,"key":"Zilean","name":"Zilean","title":"the Chronokeeper"},"Zyra":{"id":143,"key":"Zyra","name":"Zyra","title":"Rise of the Thorns"}}
--------------------------------------------------------------------------------
/api_data/dd_patch.json:
--------------------------------------------------------------------------------
1 | {"ddPatch":"7.11.1"}
--------------------------------------------------------------------------------
/api_data/index.js:
--------------------------------------------------------------------------------
1 | var items = require('./items');
2 | var masteries = require('./masteries.json');
3 | var runes = require('./runes');
4 | var skills = require('./skills');
5 | var summoners = require('./summoners');
6 |
7 | module.exports = {
8 | items: items,
9 | masteries: masteries,
10 | runes: runes,
11 | skills: skills,
12 | summoners: summoners
13 | };
--------------------------------------------------------------------------------
/api_data/masteries.json:
--------------------------------------------------------------------------------
1 | {"6111":{"id":6111,"name":"Fury","description":["+0.8% Attack Speed","+1.6% Attack Speed","+2.4% Attack Speed","+3.2% Attack Speed","+4% Attack Speed"],"image":{"full":"6111.png","sprite":"mastery0.png","group":"mastery","x":0,"y":0,"w":48,"h":48},"ranks":5,"prereq":"0"},"6114":{"id":6114,"name":"Sorcery","description":["+0.4% increased Ability damage","+0.8% increased Ability damage","+1.2% increased Ability damage","+1.6% increased Ability damage","+2.0% increased Ability damage"],"image":{"full":"6114.png","sprite":"mastery0.png","group":"mastery","x":48,"y":0,"w":48,"h":48},"ranks":5,"prereq":"0"},"6121":{"id":6121,"name":"Fresh Blood","description":["Your first basic attack against a champion deals an additional 10 +1 per level damage (6 second cooldown)"],"image":{"full":"6121.png","sprite":"mastery0.png","group":"mastery","x":96,"y":0,"w":48,"h":48},"ranks":1,"prereq":"0"},"6122":{"id":6122,"name":"Feast","description":["Killing a unit restores 20 Health (30 second cooldown)"],"image":{"full":"6122.png","sprite":"mastery0.png","group":"mastery","x":144,"y":0,"w":48,"h":48},"ranks":1,"prereq":"0"},"6123":{"id":6123,"name":"Expose Weakness","description":["Damaging enemy champions causes them to take 3% more damage from your allies"],"image":{"full":"6123.png","sprite":"mastery0.png","group":"mastery","x":192,"y":0,"w":48,"h":48},"ranks":1,"prereq":"0"},"6131":{"id":6131,"name":"Vampirism","description":["+0.4% Lifesteal and Spell Vamp","+0.8% Lifesteal and Spell Vamp","+1.2% Lifesteal and Spell Vamp","+1.6% Lifesteal and Spell Vamp","+2.0% Lifesteal and Spell Vamp"],"image":{"full":"6131.png","sprite":"mastery0.png","group":"mastery","x":240,"y":0,"w":48,"h":48},"ranks":5,"prereq":"0"},"6134":{"id":6134,"name":"Natural Talent","description":["Gain 0.4 + 0.09 per level Attack Damage, and 0.6 + 0.13 per level Ability Power (+2 Attack Damage and 3 Ability Power at level 18)","Gain 0.8 + 0.18 per level Attack Damage, and 1.2 + 0.27 per level Ability Power (+4 Attack Damage and 6 Ability Power at level 18)","Gain 1.2 + 0.27 per level Attack Damage, and 1.8 + 0.4 per level Ability Power (+6 Attack Damage and 9 Ability Power at level 18)","Gain 1.6 + 0.36 per level Attack Damage, and 2.4 + 0.53 per level Ability Power (+8 Attack Damage and 12 Ability Power at level 18)","Gain 2 + 0.44 per level Attack Damage, and 3 + 0.67 per level Ability Power (+10 Attack Damage and 15 Ability Power at level 18)"],"image":{"full":"6134.png","sprite":"mastery0.png","group":"mastery","x":288,"y":0,"w":48,"h":48},"ranks":5,"prereq":"0"},"6141":{"id":6141,"name":"Bounty Hunter","description":["Deal 1% increased damage for each unique enemy champion you have killed"],"image":{"full":"6141.png","sprite":"mastery0.png","group":"mastery","x":336,"y":0,"w":48,"h":48},"ranks":1,"prereq":"0"},"6142":{"id":6142,"name":"Double Edged Sword","description":["Deal 3% additional damage, take 1.5% additional damage."],"image":{"full":"6142.png","sprite":"mastery0.png","group":"mastery","x":384,"y":0,"w":48,"h":48},"ranks":1,"prereq":"0"},"6143":{"id":6143,"name":"Battle Trance","description":["Gain up to 3% increased damage over 3 seconds when in combat with enemy Champions"],"image":{"full":"6143.png","sprite":"mastery0.png","group":"mastery","x":432,"y":0,"w":48,"h":48},"ranks":1,"prereq":"0"},"6151":{"id":6151,"name":"Battering Blows","description":["+1.4% Armor Penetration","+2.8% Armor Penetration","+4.2% Armor Penetration","+5.6% Armor Penetration","+7% Armor Penetration"],"image":{"full":"6151.png","sprite":"mastery0.png","group":"mastery","x":0,"y":48,"w":48,"h":48},"ranks":5,"prereq":"0"},"6154":{"id":6154,"name":"Piercing Thoughts","description":["+1.4% Magic Penetration","+2.8% Magic Penetration","+4.2% Magic Penetration","+5.6% Magic Penetration","+7% Magic Penetration"],"image":{"full":"6154.png","sprite":"mastery0.png","group":"mastery","x":48,"y":48,"w":48,"h":48},"ranks":5,"prereq":"0"},"6161":{"id":6161,"name":"Warlord's Bloodlust","description":["Moving or attacking will charge an Energized attack. Energized attacks heal for 5-40% of your total Attack Damage (amplified by Critical Strikes) and grant 30% Movement Speed for 0.75 seconds."],"image":{"full":"6161.png","sprite":"mastery0.png","group":"mastery","x":96,"y":48,"w":48,"h":48},"ranks":1,"prereq":"0"},"6162":{"id":6162,"name":"Fervor of Battle","description":["Hitting champions with basic attacks generates a Fervor stack (2 for melee attacks). Stacks of Fervor last 8 seconds (max 8 stacks)and increase your AD by 1-8 for each stack."],"image":{"full":"6162.png","sprite":"mastery0.png","group":"mastery","x":144,"y":48,"w":48,"h":48},"ranks":1,"prereq":"0"},"6164":{"id":6164,"name":"Deathfire Touch","description":["Your damaging abilities cause enemy champions to take magic damage over 4 seconds.
Damage: 8 + 45% Bonus Attack Damage and 25% Ability Power
Deathfire Touch's duration is reduced for:
- Area of Effect: 2 second duration.
- Damage over Time: 1 second duration."],"image":{"full":"6164.png","sprite":"mastery0.png","group":"mastery","x":192,"y":48,"w":48,"h":48},"ranks":1,"prereq":"0"},"6211":{"id":6211,"name":"Recovery","description":["+0.4 Health per 5 seconds","+0.8 Health per 5 seconds","+1.2 Health per 5 seconds","+1.6 Health per 5 seconds","+2.0 Health per 5 seconds"],"image":{"full":"6211.png","sprite":"mastery0.png","group":"mastery","x":0,"y":144,"w":48,"h":48},"ranks":5,"prereq":"0"},"6212":{"id":6212,"name":"Unyielding","description":["+1% Bonus Armor and Magic Resist","+2% Bonus Armor and Magic Resist","+3% Bonus Armor and Magic Resist","+4% Bonus Armor and Magic Resist","+5% Bonus Armor and Magic Resist"],"image":{"full":"6212.png","sprite":"mastery0.png","group":"mastery","x":48,"y":144,"w":48,"h":48},"ranks":5,"prereq":"0"},"6221":{"id":6221,"name":"Explorer","description":["+15 Movement Speed in Brush and River"],"image":{"full":"6221.png","sprite":"mastery0.png","group":"mastery","x":96,"y":144,"w":48,"h":48},"ranks":1,"prereq":"0"},"6222":{"id":6222,"name":"Siegemaster","description":["Gain 8 Armor and Magic Resistance when near an allied tower"],"image":{"full":"6222.png","sprite":"mastery0.png","group":"mastery","x":192,"y":144,"w":48,"h":48},"ranks":1,"prereq":"0"},"6223":{"id":6223,"name":"Tough Skin","description":["You take 2 less damage from champion and neutral monster basic attacks"],"image":{"full":"6223.png","sprite":"mastery0.png","group":"mastery","x":144,"y":144,"w":48,"h":48},"ranks":1,"prereq":"0"},"6231":{"id":6231,"name":"Runic Armor","description":["Shields, healing, regeneration, and lifesteal on you are 1.6% stronger","Shields, healing, regeneration, and lifesteal on you are 3.2% stronger","Shields, healing, regeneration, and lifesteal on you are 4.8% stronger","Shields, healing, regeneration, and lifesteal on you are 6.4% stronger","Shields, healing, regeneration, and lifesteal on you are 8% stronger"],"image":{"full":"6231.png","sprite":"mastery0.png","group":"mastery","x":240,"y":144,"w":48,"h":48},"ranks":5,"prereq":"0"},"6232":{"id":6232,"name":"Veteran's Scars","description":["+10 Health","+20 Health","+30 Health","+40 Health","+50 Health"],"image":{"full":"6232.png","sprite":"mastery0.png","group":"mastery","x":288,"y":144,"w":48,"h":48},"ranks":5,"prereq":"0"},"6241":{"id":6241,"name":"Insight","description":["Reduces the cooldown of Summoner Spells by 15%"],"image":{"full":"6241.png","sprite":"mastery0.png","group":"mastery","x":336,"y":144,"w":48,"h":48},"ranks":1,"prereq":"0"},"6242":{"id":6242,"name":"Perseverance","description":["+50% Base Health Regen, increased to +200% when below 25% Health"],"image":{"full":"6242.png","sprite":"mastery0.png","group":"mastery","x":384,"y":144,"w":48,"h":48},"ranks":1,"prereq":"0"},"6243":{"id":6243,"name":"Fearless","description":["Gain 10% +1.5 per level bonus Armor and Magic Resist when damaged by an enemy champion for 2 seconds (9s Cooldown)"],"image":{"full":"6243.png","sprite":"mastery0.png","group":"mastery","x":432,"y":144,"w":48,"h":48},"ranks":1,"prereq":"0"},"6251":{"id":6251,"name":"Swiftness","description":["+3% Tenacity and Slow Resist","+6% Tenacity and Slow Resist","+9% Tenacity and Slow Resist","+12% Tenacity and Slow Resist","+15% Tenacity and Slow Resist"],"image":{"full":"6251.png","sprite":"mastery0.png","group":"mastery","x":0,"y":192,"w":48,"h":48},"ranks":5,"prereq":"0"},"6252":{"id":6252,"name":"Legendary Guardian","description":["+0.6 Armor and Magic Resist for each nearby enemy champion","+1.2 Armor and Magic Resist for each nearby enemy champion","+1.8 Armor and Magic Resist for each nearby enemy champion","+2.4 Armor and Magic Resist for each nearby enemy champion","+3 Armor and Magic Resist for each nearby enemy champion"],"image":{"full":"6252.png","sprite":"mastery0.png","group":"mastery","x":48,"y":192,"w":48,"h":48},"ranks":5,"prereq":"0"},"6261":{"id":6261,"name":"Grasp of the Undying","description":["Every 4 seconds in combat, your next attack against an enemy champion deals damage equal to 3% of your max Health and heals you for 1.5% of your max Health (halved for ranged champions, deals magic damage)"],"image":{"full":"6261.png","sprite":"mastery0.png","group":"mastery","x":96,"y":192,"w":48,"h":48},"ranks":1,"prereq":"0"},"6262":{"id":6262,"name":"Courage of the Colossus","description":["Gain a shield for 3-54 (+5% of your maximum health) for each nearby enemy champion for 3 seconds after hitting an enemy champion with a stun, taunt, snare, or knock up (45-30 second cooldown, based on level)."],"image":{"full":"6262.png","sprite":"mastery0.png","group":"mastery","x":144,"y":192,"w":48,"h":48},"ranks":1,"prereq":"0"},"6263":{"id":6263,"name":"Stoneborn Pact","description":["Gain 5% total health.
Your movement impairing effects brand enemy champions with an earthen rune for 4 seconds. Other allied champions who attack branded enemies heal for 5 + 2.5% of your maximum health over 2 seconds (halved if you are ranged)."],"image":{"full":"6263.png","sprite":"mastery0.png","group":"mastery","x":192,"y":192,"w":48,"h":48},"ranks":1,"prereq":"0"},"6311":{"id":6311,"name":"Wanderer","description":["+0.6% Movement Speed out of combat","+1.2% Movement Speed out of combat","+1.8% Movement Speed out of combat","+2.4% Movement Speed out of combat","+3% Movement Speed out of combat"],"image":{"full":"6311.png","sprite":"mastery0.png","group":"mastery","x":240,"y":48,"w":48,"h":48},"ranks":5,"prereq":"0"},"6312":{"id":6312,"name":"Savagery","description":["Single target attacks and spells deal 1 bonus damage to minions and monsters","Single target attacks and spells deal 2 bonus damage to minions and monsters","Single target attacks and spells deal 3 bonus damage to minions and monsters","Single target attacks and spells deal 4 bonus damage to minions and monsters","Single target attacks and spells deal 5 bonus damage to minions and monsters"],"image":{"full":"6312.png","sprite":"mastery0.png","group":"mastery","x":288,"y":48,"w":48,"h":48},"ranks":5,"prereq":"0"},"6321":{"id":6321,"name":"Runic Affinity","description":["Buffs from neutral monsters last 15% longer"],"image":{"full":"6321.png","sprite":"mastery0.png","group":"mastery","x":336,"y":48,"w":48,"h":48},"ranks":1,"prereq":"0"},"6322":{"id":6322,"name":"Secret Stash","description":["Your Potions and Elixirs last 10% longer.
Your Health Potions are replaced with Biscuits that restore 15 Health and Mana instantly on use"],"image":{"full":"6322.png","sprite":"mastery0.png","group":"mastery","x":384,"y":48,"w":48,"h":48},"ranks":1,"prereq":"0"},"6323":{"id":6323,"name":"Assassin","description":["Deal 2% increased damage to champions when no allied champions are nearby"],"image":{"full":"6323.png","sprite":"mastery0.png","group":"mastery","x":432,"y":48,"w":48,"h":48},"ranks":1,"prereq":"0"},"6331":{"id":6331,"name":"Merciless","description":["Deal 0.6% increased damage to champions below 40% Health","Deal 1.2% increased damage to champions below 40% Health","Deal 1.8% increased damage to champions below 40% Health","Deal 2.4% increased damage to champions below 40% Health","Deal 3% increased damage to champions below 40% Health"],"image":{"full":"6331.png","sprite":"mastery0.png","group":"mastery","x":0,"y":96,"w":48,"h":48},"ranks":5,"prereq":"0"},"6332":{"id":6332,"name":"Meditation","description":["Regenerate 0.25% of your missing Mana every 5 seconds","Regenerate 0.5% of your missing Mana every 5 seconds","Regenerate 0.75% of your missing Mana every 5 seconds","Regenerate 1.0% of your missing Mana every 5 seconds","Regenerate 1.25% of your missing Mana every 5 seconds"],"image":{"full":"6332.png","sprite":"mastery0.png","group":"mastery","x":48,"y":96,"w":48,"h":48},"ranks":5,"prereq":"0"},"6341":{"id":6341,"name":"Greenfather's Gift","description":["Stepping into brush causes your next damaging attack or ability to deal 3% of your target's current health as bonus magic damage (9s Cooldown)"],"image":{"full":"6341.png","sprite":"mastery0.png","group":"mastery","x":96,"y":96,"w":48,"h":48},"ranks":1,"prereq":"0"},"6342":{"id":6342,"name":"Bandit","description":["Gain 1 gold for each nearby minion killed by an ally.
Gain 3 gold (10 if melee) when hitting an enemy champion with a basic attack (5 second cooldown)"],"image":{"full":"6342.png","sprite":"mastery0.png","group":"mastery","x":144,"y":96,"w":48,"h":48},"ranks":1,"prereq":"0"},"6343":{"id":6343,"name":"Dangerous Game","description":["Champion kills and assists restore 5% of your missing Health and Mana"],"image":{"full":"6343.png","sprite":"mastery0.png","group":"mastery","x":192,"y":96,"w":48,"h":48},"ranks":1,"prereq":"0"},"6351":{"id":6351,"name":"Precision","description":["Gain 1.2 Lethality and 0.3 + 0.05 per level Magic Penetration","Gain 2.4 Lethality and 0.6 + 0.10 per level Magic Penetration","Gain 3.6 Lethality and 0.9 + 0.15 per level Magic Penetration","Gain 4.8 Lethality and 1.2 + 0.20 per level Magic Penetration","Gain 6 Lethality and 1.5 + 0.25 per level Magic Penetration"],"image":{"full":"6351.png","sprite":"mastery0.png","group":"mastery","x":240,"y":96,"w":48,"h":48},"ranks":5,"prereq":"0"},"6352":{"id":6352,"name":"Intelligence","description":["Your Cooldown Reduction cap is increased to 41% and you gain 1% Cooldown Reduction","Your Cooldown Reduction cap is increased to 42% and you gain 2% Cooldown Reduction","Your Cooldown Reduction cap is increased to 43% and you gain 3% Cooldown Reduction","Your Cooldown Reduction cap is increased to 44% and you gain 4% Cooldown Reduction","Your Cooldown Reduction cap is increased to 45% and you gain 5% Cooldown Reduction"],"image":{"full":"6352.png","sprite":"mastery0.png","group":"mastery","x":288,"y":96,"w":48,"h":48},"ranks":5,"prereq":"0"},"6361":{"id":6361,"name":"Stormraider's Surge","description":["Dealing 30% of a champion's max Health within 2.5 seconds grants you 40% Movement Speed and 75% Slow Resistance for 3 seconds (10 second cooldown)."],"image":{"full":"6361.png","sprite":"mastery0.png","group":"mastery","x":336,"y":96,"w":48,"h":48},"ranks":1,"prereq":"0"},"6362":{"id":6362,"name":"Thunderlord's Decree","description":["Your 3rd attack or damaging spell against the same enemy champion calls down a lightning strike, dealing magic damage in the area.
Damage: 10 per level, plus 30% of your Bonus Attack Damage, and 10% of your Ability Power (25-15 second cooldown, based on level)."],"image":{"full":"6362.png","sprite":"mastery0.png","group":"mastery","x":384,"y":96,"w":48,"h":48},"ranks":1,"prereq":"0"},"6363":{"id":6363,"name":"Windspeaker's Blessing","description":["Your heals and shields are 10% stronger. Additionally, your shields and heals on other allies increase their armor by 5-22 (based on level) and their magic resistance by half that amount for 3 seconds."],"image":{"full":"6363.png","sprite":"mastery0.png","group":"mastery","x":432,"y":96,"w":48,"h":48},"ranks":1,"prereq":"0"}}
--------------------------------------------------------------------------------
/api_data/runes.js:
--------------------------------------------------------------------------------
1 | module.exports = '';
--------------------------------------------------------------------------------
/app.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var express = require('express');
3 | var http = require('http');
4 | var path = require('path');
5 | var favicon = require('serve-favicon');
6 | var logger = require('morgan');
7 | var bodyParser = require('body-parser');
8 | var compress = require('compression');
9 |
10 | //middle ware
11 | var overallData = require('./middleware/overall_data.js');
12 |
13 | //routes
14 | var champion = require('./routes/champion');
15 | var matchup = require('./routes/matchup');
16 | var matchupJson = require('./routes/matchup_json');
17 | var apiStatic = require('./routes/api_static');
18 | var statistics = require('./routes/statistics');
19 | var faq = require('./routes/faq');
20 | var index = require('./routes/index');
21 |
22 | var app = express();
23 |
24 | app.get('/*', function(req, res, next) { // redirect to http instead of www
25 | if (req.headers.host.match(/^www/) !== null ) {
26 | res.redirect('http://' + req.headers.host.replace(/^www\./, '') + req.url);
27 | } else {
28 | next();
29 | }
30 | });
31 |
32 | // view engine setup
33 | app.set('views', path.join(__dirname, 'views'));
34 | app.set('view engine', 'ejs');
35 |
36 | app.use(compress());
37 | app.use(favicon(__dirname + '/public/favicon.ico'));
38 | app.use(logger('dev'));
39 | app.use(bodyParser.json({limit: '2kb', extended: true}));
40 | app.use(bodyParser.urlencoded({limit: '2kb', extended: true}));
41 |
42 | app.use(express.static(path.join(__dirname, 'public'), {maxAge:86400000})); //one day
43 |
44 | //pages
45 | //set cache headers for page now that we are utilizing cloudflare
46 | app.use(function(req, res, next){
47 | res.setHeader('Cache-Control', 'public, max-age=86400'); //cache pages for 1 minute, if needed I can purge cache from cloud flare
48 | next();
49 | });
50 |
51 | app.use(overallData);
52 |
53 | app.use('/champion', champion);
54 | app.use('/matchup', matchup);
55 | app.use('/matchupJson', matchupJson);
56 | app.use('/static', apiStatic);
57 |
58 | app.use('/statistics', statistics);
59 | app.use('/faq', faq);
60 | app.use('/', index);
61 |
62 | /// catch 404 and forwarding to error handler
63 | app.use(function(req, res, next) {
64 | var err = new Error('Not Found');
65 | err.status = 404;
66 | next(err);
67 | });
68 |
69 | /// error handlers
70 |
71 | // development error handler
72 | // will print stacktrace
73 |
74 | if (app.get('env') === 'development') {
75 | app.use(function(err, req, res, next) {
76 | res.statusCode = err.status;
77 | res.render('error', {
78 | pageData:{
79 | appName: 'core',
80 | name:'error',
81 | title: 'We got ourselves a problem...'
82 | },
83 | message: err.message,
84 | error: err
85 | });
86 | });
87 | } else {
88 | // production error handler
89 | // no stacktraces leaked to user
90 | app.use(function(err, req, res, next) {
91 | res.statusCode = err.status;
92 | res.render('error', {
93 | pageData:{
94 | appName: 'core',
95 | name:'error',
96 | title: 'We got ourselves a wild teemo problem...'
97 | },
98 | message: err.message,
99 | error: {}
100 | });
101 | });
102 | }
103 |
104 | module.exports = app;
105 |
--------------------------------------------------------------------------------
/bash.txt:
--------------------------------------------------------------------------------
1 | Mongodump file
2 | mongodump --db championgg --collection webchampionpages --out ./db
3 | mongodump --db championgg --collection webchampionroles --out ./db
4 | mongodump --db championgg --collection webmatchuppages --out ./db
5 | mongodump --db championgg --collection weboverallroledatas --out ./db
6 | mongodump --db championgg --collection webhomepagesummaries --out ./db
7 | mongodump --db championgg --collection webstatisticspages --out ./db
8 | mongodump --db championgg --collection weboverallrolestats --out ./db
9 | git add -A && git commit -m "updated data" && git push
10 |
11 |
12 | cd /code/championweb
13 | git pull
14 | mongorestore --db championgg --collection webchampionpages --drop db/championgg/webchampionpages.bson
15 | mongorestore --db championgg --collection webchampionroles --drop db/championgg/webchampionroles.bson
16 | mongorestore --db championgg --collection webmatchuppages --drop db/championgg/webmatchuppages.bson
17 | mongorestore --db championgg --collection weboverallroledatas --drop db/championgg/weboverallroledatas.bson
18 | mongorestore --db championgg --collection webhomepagesummaries --drop db/championgg/webhomepagesummaries.bson
19 | mongorestore --db championgg --collection webstatisticspages --drop db/championgg/webstatisticspages.bson
20 | mongorestore --db championgg --collection weboverallroledatas --drop db/championgg/weboverallstats.bson
21 | cd bin && NODE_ENV=production pm2 restart www.js
22 |
23 |
24 | NODE_ENV=production pm2 restart www.js
25 | NODE_ENV=updating pm2 restart www.js
26 | NODE_ENV=serverUpdate pm2 restart www.js
27 |
28 | NODE_ENV=production pm2 start www.js -i max
29 | NODE_ENV=updating pm2 start www.js -i max
30 | NODE_ENV=serverUpdate pm2 start www.js -i max
31 |
32 |
33 | UPDATES=aggregation node performUpdate
34 |
35 | mongodump --db leaguetimes --collection votes
36 |
--------------------------------------------------------------------------------
/bin/update_server.sh:
--------------------------------------------------------------------------------
1 | sudo npm install
2 | mongorestore --db championgg --collection webchampionpages --drop db/championgg/webchampionpages.bson
3 | mongorestore --db championgg --collection webchampionroles --drop db/championgg/webchampionroles.bson
4 | mongorestore --db championgg --collection webmatchuppages --drop db/championgg/webmatchuppages.bson
5 | mongorestore --db championgg --collection weboverallroledatas --drop db/championgg/weboverallroledatas.bson
6 | mongorestore --db championgg --collection weboverallstats --drop db/championgg/weboverallstats.bson
7 | mongorestore --db championgg --collection webhomepagesummaries --drop db/championgg/webhomepagesummaries.bson
8 | mongorestore --db championgg --collection webstatisticspages --drop db/championgg/webstatisticspages.bson
9 | cd bin && NODE_ENV=production pm2 restart www.js
10 |
--------------------------------------------------------------------------------
/bin/www.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | "use strict";
3 | var debug = require('debug')('my-application');
4 | var app = require('../app');
5 | var db = require('../db');
6 |
7 | app.set('port', process.env.PORT || 80);
8 |
9 | app.listen(app.get('port'), function() {
10 | console.log('Express server listening on port ' + app.get('port'));
11 | });
12 |
--------------------------------------------------------------------------------
/config/config.js:
--------------------------------------------------------------------------------
1 | module.exports.config = {
2 | worker: {
3 | local: {
4 | githubRoot: 'https://raw.githubusercontent.com/joel1st/championweb/master/',
5 | githubRoute : 'https://raw.githubusercontent.com/joel1st/championweb/master/db/championgg/',
6 | files: [
7 | 'webchampionpages.bson',
8 | 'webchampionpages.metadata.json',
9 | 'webchampionroles.bson',
10 | 'webchampionroles.metadata.json',
11 | 'webhomepagesummaries.bson',
12 | 'webhomepagesummaries.metadata.json',
13 | 'webmatchuppages.bson',
14 | 'webmatchuppages.metadata.json',
15 | 'weboverallroledatas.bson',
16 | 'weboverallroledatas.metadata.json',
17 | 'weboverallstats.bson',
18 | 'weboverallstats.metadata.json',
19 | 'webstatisticspages.bson',
20 | 'webstatisticspages.metadata.json'
21 | ],
22 | headline: 'headline.js',
23 | tmpFolder: 'tmp/',
24 | mongo: {
25 | host: 'localhost',
26 | port: '27017',
27 | db: 'championgg',
28 | user: '',
29 | password: ''
30 | },
31 | queue: {
32 | prefix: 'championggQ_',
33 | host: 'localhost',
34 | pass: '',
35 | port: 6379
36 | },
37 | fastly: {
38 | api_key: process.env.FASTLY_API_KEY,
39 | purgeall: 'https://api.fastly.com/service/' + process.env.FASTLY_SERVICE_ID + '/purge_all'
40 | }
41 | },
42 | production: {
43 | githubRoot: 'https://raw.githubusercontent.com/joel1st/championweb/master/',
44 | githubRoute : 'https://raw.githubusercontent.com/joel1st/championweb/master/db/championgg/',
45 | files: [
46 | 'webchampionpages.bson',
47 | 'webchampionpages.metadata.json',
48 | 'webchampionroles.bson',
49 | 'webchampionroles.metadata.json',
50 | 'webhomepagesummaries.bson',
51 | 'webhomepagesummaries.metadata.json',
52 | 'webmatchuppages.bson',
53 | 'webmatchuppages.metadata.json',
54 | 'weboverallroledatas.bson',
55 | 'weboverallroledatas.metadata.json',
56 | 'weboverallstats.bson',
57 | 'weboverallstats.metadata.json',
58 | 'webstatisticspages.bson',
59 | 'webstatisticspages.metadata.json'
60 | ],
61 | headline: 'headline.js',
62 | tmpFolder: 'tmp/',
63 | mongo: {
64 | host: process.env.WORKER_MONGO_HOST,
65 | port: process.env.WORKER_MONGO_PORT,
66 | db: process.env.WORKER_MONGO_DB,
67 | user: process.env.WORKER_MONGO_USER,
68 | password: process.env.WORKER_MONGO_PASSWORD
69 | },
70 | queue: {
71 | prefix: process.env.QUEUE_PREFIX || 'championggQ_',
72 | host: process.env.REDIS_HOST || 'localhost',
73 | pass: process.env.REDIS_PASS || '',
74 | port: process.env.REDIS_PORT || 6379
75 | },
76 | fastly: {
77 | api_key: process.env.FASTLY_API_KEY,
78 | purgeall: 'https://api.fastly.com/service/' + process.env.FASTLY_SERVICE_ID + '/purge_all'
79 | }
80 | }
81 | }
82 | };
83 |
--------------------------------------------------------------------------------
/db.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var mongoose = require('mongoose');
3 | mongoose.connect(process.env.MONGO_DB || 'mongodb://localhost/championgg');
4 | var db = mongoose.connection;
5 |
6 | db.on('error', console.error.bind(console, 'connection error:'));
7 |
8 | db.once('open', function () {
9 | console.log('Connection Made!');
10 | });
11 |
--------------------------------------------------------------------------------
/db/championgg/webchampionpages.bson:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joel1st/championweb/f98e5d775bc903d1454d8e41651770fbf44d434b/db/championgg/webchampionpages.bson
--------------------------------------------------------------------------------
/db/championgg/webchampionpages.metadata.json:
--------------------------------------------------------------------------------
1 | { "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "championgg.webchampionpages" } ] }
--------------------------------------------------------------------------------
/db/championgg/webchampionroles.bson:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joel1st/championweb/f98e5d775bc903d1454d8e41651770fbf44d434b/db/championgg/webchampionroles.bson
--------------------------------------------------------------------------------
/db/championgg/webchampionroles.metadata.json:
--------------------------------------------------------------------------------
1 | { "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "championgg.webchampionroles" } ] }
--------------------------------------------------------------------------------
/db/championgg/webhomepagesummaries.bson:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joel1st/championweb/f98e5d775bc903d1454d8e41651770fbf44d434b/db/championgg/webhomepagesummaries.bson
--------------------------------------------------------------------------------
/db/championgg/webhomepagesummaries.metadata.json:
--------------------------------------------------------------------------------
1 | { "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "championgg.webhomepagesummaries" } ] }
--------------------------------------------------------------------------------
/db/championgg/webmatchuppages.bson:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joel1st/championweb/f98e5d775bc903d1454d8e41651770fbf44d434b/db/championgg/webmatchuppages.bson
--------------------------------------------------------------------------------
/db/championgg/webmatchuppages.metadata.json:
--------------------------------------------------------------------------------
1 | { "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "championgg.webmatchuppages" } ] }
--------------------------------------------------------------------------------
/db/championgg/weboverallroledatas.bson:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joel1st/championweb/f98e5d775bc903d1454d8e41651770fbf44d434b/db/championgg/weboverallroledatas.bson
--------------------------------------------------------------------------------
/db/championgg/weboverallroledatas.metadata.json:
--------------------------------------------------------------------------------
1 | { "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "championgg.weboverallroledatas" } ] }
--------------------------------------------------------------------------------
/db/championgg/weboverallstats.bson:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joel1st/championweb/f98e5d775bc903d1454d8e41651770fbf44d434b/db/championgg/weboverallstats.bson
--------------------------------------------------------------------------------
/db/championgg/weboverallstats.metadata.json:
--------------------------------------------------------------------------------
1 | { "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "championgg.weboverallstats" } ] }
--------------------------------------------------------------------------------
/db/championgg/webstatisticspages.bson:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joel1st/championweb/f98e5d775bc903d1454d8e41651770fbf44d434b/db/championgg/webstatisticspages.bson
--------------------------------------------------------------------------------
/db/championgg/webstatisticspages.metadata.json:
--------------------------------------------------------------------------------
1 | { "indexes" : [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "championgg.webstatisticspages" } ] }
--------------------------------------------------------------------------------
/gruntfile.js:
--------------------------------------------------------------------------------
1 | module.exports = function(grunt){
2 | "use strict";
3 | require("matchdep").filterDev("grunt-*").forEach(grunt.loadNpmTasks);
4 |
5 | grunt.initConfig({
6 | watch: {
7 | js: {
8 | files: [
9 | 'routes/*.js',
10 | 'bin/*.js',
11 | 'logic/*.js',
12 | 'models/*.js',
13 | 'public/js/*.js',
14 | '*.js'
15 | ],
16 | tasks: ['jshint']
17 | }
18 | },
19 | pkg: grunt.file.readJSON('package.json'),
20 | jshint: {
21 | files: [
22 | 'routes/*.js',
23 | 'bin/*.js',
24 | 'logic/*.js',
25 | 'models/*.js',
26 | 'public/js/*.js',
27 | '!public/js/master.min.js',
28 | '*.js'
29 | ],
30 | options: {
31 | // options here to override JSHint defaults
32 | node: true,
33 | loopfunc: true,
34 | globals: {
35 | jQuery: false,
36 | console: true,
37 | module: true,
38 | require: true
39 | }
40 | }
41 | },
42 | concat: {
43 | js: {
44 | src: ['public/dist/js/angular.js', 'public/dist/js/angular-bootstrap.js',
45 | 'public/dist/js/dirDisqus.js', 'public/dist/js/chart.js',
46 | 'public/dist/js/tc-angular-chartjs.js', 'public/js/champion_data.js', 'public/js/chart_options.js', 'public/js/championgg_tooltip.js',
47 | 'public/js/app.js', 'public/js/champion_page.js', 'public/js/matchup_page.js', 'public/js/statistics_page.js'],
48 | dest: 'public/js/master.min.js'
49 | },
50 | },
51 | uglify: {
52 | build: {
53 | files: {
54 | 'public/js/master.min.js': 'public/js/master.min.js'
55 | }
56 | }
57 | },
58 | cssmin: {
59 | build: {
60 | src: ['public/css/master.css', 'public/css/sprite.css'],
61 | dest: 'public/css/master.min.css'
62 | }
63 | }
64 | });
65 |
66 | grunt.registerTask('production', ['concat', 'uglify','cssmin']);
67 | grunt.registerTask('default', []);
68 | };
--------------------------------------------------------------------------------
/headline.js:
--------------------------------------------------------------------------------
1 | // Message to display at the top of the site.
2 | // Standard message: We are currently aggregating patch 6.14 data - check back in 3 days!
3 | module.exports = "";
4 |
--------------------------------------------------------------------------------
/logic/lower_case_champ.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var champList = require('../api_data/champions.json');
3 |
4 | /**
5 | * Converts the champion list keys to lower case. It then compares
6 | * the input to see if there is a match. (this is useful for checking,
7 | * if a url has entered a champion key - but doesn't match the correct casing).
8 | * @param {string} champName - the champ name to compare against the champList.
9 | * @return {string|undefined} - if a match is found, the champ key is returned, otherwise undefined.
10 | */
11 | var lowerCaseChamp = function(champName) {
12 | for (var prop in champList) {
13 | if (prop.toLowerCase() === champName.toLowerCase()) {
14 | return prop;
15 | }
16 | }
17 | };
18 |
19 |
20 | module.exports = lowerCaseChamp;
--------------------------------------------------------------------------------
/logic/produce_error.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | var errors = {
3 | champNotFound: 'That champ or role doesn\'t appear to exist!',
4 | pageNotFound: 'We couldn\'t find the page you are looking for - sorry!',
5 | serverMaintenance: 'For some reason we couldn\'t get the page to load - Chances are we\'re working on updating data - if it isn\'t fixed in the next few minutes please let us know!',
6 | invalidMatchup: 'That appears to be an invalid or old matchup!'
7 | };
8 |
9 | /**
10 | * A function for generating errors.
11 | * @param {string} errorType - the key for the error type (which corresponds with the keys
12 | * in the error object above).
13 | * @param {number} errorNumber - the response number of the error (defaults to 404).
14 | * @return {object} - the error object.
15 | */
16 | var produceError = function(errorType, errorNumber) {
17 | var err = new Error(errors[errorType]);
18 | err.status = errorNumber || 404;
19 | return err;
20 | };
21 |
22 | module.exports = produceError;
--------------------------------------------------------------------------------
/logic/role_hash_table.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | /**
3 | * The varius role keys and values.
4 | * Used for determining legitimate roles for champion page routes.
5 | */
6 | var roleList = {
7 | 'Top': 'TOP',
8 | 'Middle': 'MIDDLE',
9 | 'Support': 'DUO_SUPPORT',
10 | 'ADC': 'DUO_CARRY',
11 | 'Jungle': 'JUNGLE',
12 | 'top': 'TOP',
13 | 'middle': 'MIDDLE',
14 | 'support': 'DUO_SUPPORT',
15 | 'adc': 'DUO_CARRY',
16 | 'jungle': 'JUNGLE',
17 | 'adcsupport': 'ADCSUPPORT',
18 | 'synergy': 'SYNERGY'
19 | };
20 |
21 | var roleKey = {
22 | 'TOP': 'Top',
23 | 'MIDDLE': 'Middle',
24 | 'DUO_SUPPORT': 'Support',
25 | 'DUO_CARRY': 'ADC',
26 | 'JUNGLE': 'Jungle',
27 | 'ADCSUPPORT': 'adcsupport',
28 | 'SYNERGY': 'synergy'
29 | };
30 |
31 | exports.roleList = roleList;
32 | exports.roleKey = roleKey;
--------------------------------------------------------------------------------
/middleware/overall_data.js:
--------------------------------------------------------------------------------
1 | var WebOverallStats = require('../models/web_overall_stats.js');
2 | var produceError = require('../logic/produce_error.js');
3 |
4 | /**
5 | * The core object is used in all views template for overall data.
6 | * Values from database are loaded from the webOverallStats
7 | * collection and added to core object.
8 | * @type {Object}
9 | */
10 | var ddPatch = require('../api_data/dd_patch.json').ddPatch
11 | var core = {
12 | ddPatch: ddPatch,
13 | resetCache: ddPatch + Math.random().toFixed(6),
14 | masteryOrder: ['Offense','Defense','Utility'],
15 | headline: require('../headline.js')
16 | };
17 | // Data retrieved from DB:
18 | // gamesAnalyzed:"3,549,640",
19 | // patch:"5.10",
20 | // patchHistory: ["5.6","5.7","5.8","5.9","5.10"]
21 |
22 | module.exports = function(req, res, next){
23 | /**
24 | * Set the core object as a local for the view
25 | */
26 | res.locals.core = core;
27 |
28 | /**
29 | * If no data has been retrieved from data base yet,
30 | * request overall stats data from collection and add it
31 | * to the core object.
32 | */
33 | if (!core.championsAnalyzed){
34 | WebOverallStats.findOne({}, function(err, data) {
35 | if (err) {
36 | return next(produceError('serverMaintenance', 503));
37 | } else if (!data) {
38 | return next(produceError('serverMaintenance', 503));
39 | } else {
40 | core.championsAnalyzed = data.championsAnalyzed;
41 | core.patch = data.patch;
42 | core.patchHistory = data.patchHistory;
43 | next();
44 | }
45 | });
46 | } else {
47 | next();
48 | }
49 | };
50 |
--------------------------------------------------------------------------------
/models/web_champion_page.js:
--------------------------------------------------------------------------------
1 | var mongoose = require('mongoose');
2 |
3 | var webChampionPage = new mongoose.Schema({
4 | role: String,
5 | key: String,
6 | general: [{
7 | title:String,
8 | titleLink: String,
9 | val:String,
10 | position:Number,
11 | change:Number
12 | }],
13 | overallPosition: {
14 | position: Number,
15 | change:Number
16 | },
17 | championMatrix:[Number],
18 | patchPlay:[Number],
19 | gameLength:[Number],
20 | experienceRate:[Number],
21 | experienceSample:[Number],
22 | patchWin:[Number],
23 | dmgComposition:{
24 | physicalDmg: Number,
25 | magicDmg: Number,
26 | trueDmg: Number
27 | },
28 | items:{
29 | mostGames: {
30 | items: [{
31 | id:Number,
32 | name:String,
33 | }],
34 | games: Number,
35 | winPercent: Number
36 | },
37 | highestWinPercent: {
38 | items: [{
39 | id:Number,
40 | name:String,
41 | }],
42 | games: Number,
43 | winPercent: Number
44 | }
45 | },
46 | firstItems:{
47 | mostGames: {
48 | items: [{
49 | id:Number,
50 | name:String,
51 | }],
52 | games: Number,
53 | winPercent: Number
54 | },
55 | highestWinPercent: {
56 | items: [{
57 | id:Number,
58 | name:String,
59 | }],
60 | games: Number,
61 | winPercent: Number
62 | }
63 | },
64 | trinkets: [{
65 | item: {
66 | id:Number,
67 | name:String,
68 | },
69 | games: Number,
70 | winPercent: Number
71 | }],
72 | summoners:{
73 | mostGames: {
74 | summoner1: {
75 | name:String,
76 | url: String
77 | },
78 | summoner2: {
79 | name:String,
80 | url: String
81 | },
82 | games: Number,
83 | winPercent: Number
84 | },
85 | highestWinPercent: {
86 | summoner1: {
87 | name:String,
88 | url: String
89 | },
90 | summoner2: {
91 | name:String,
92 | url: String
93 | },
94 | games: Number,
95 | winPercent: Number
96 | }
97 | },
98 | skills:{
99 | skillInfo: [{
100 | name: String,
101 | img: String,
102 | key: String
103 | }],
104 | mostGames: {
105 | order: [String],
106 | games: Number,
107 | winPercent: Number
108 | },
109 | highestWinPercent: {
110 | order: [String],
111 | games: Number,
112 | winPercent: Number
113 | }
114 | },
115 | masteries:{
116 | mostGames: {
117 | masteries: [{
118 | tree: String,
119 | total: Number,
120 | data: {row1: [{mastery:Number, points:Number}],
121 | row2: [{mastery:Number, points:Number}],
122 | row3: [{mastery:Number, points:Number}],
123 | row4: [{mastery:Number, points:Number}],
124 | row5: [{mastery:Number, points:Number}],
125 | row6: [{mastery:Number, points:Number}]}
126 | }],
127 | games: Number,
128 | winPercent: Number
129 | },
130 | highestWinPercent: {
131 | masteries: [{
132 | tree: String,
133 | total: Number,
134 | data: {row1: [{mastery:Number, points:Number}],
135 | row2: [{mastery:Number, points:Number}],
136 | row3: [{mastery:Number, points:Number}],
137 | row4: [{mastery:Number, points:Number}],
138 | row5: [{mastery:Number, points:Number}],
139 | row6: [{mastery:Number, points:Number}]}
140 | }],
141 | games: Number,
142 | winPercent: Number
143 | }
144 | },
145 | runes:{
146 | mostGames: {
147 | runes: [{
148 | id: Number,
149 | number: Number,
150 | name: String,
151 | img: String,
152 | description: String,
153 | }],
154 | games: Number,
155 | winPercent: Number
156 | },
157 | highestWinPercent: {
158 | runes: [{
159 | id: Number,
160 | number: Number,
161 | name: String,
162 | img: String,
163 | description: String,
164 | }],
165 | games: Number,
166 | winPercent: Number
167 | }
168 | },
169 | unique:{ //champions like viktor
170 | mostGames: {
171 | order: [Number],
172 | games: Number,
173 | winPercent: Number
174 | },
175 | highestWinPercent: {
176 | order: [Number],
177 | games: Number,
178 | winPercent: Number
179 | }
180 | },
181 | matchups:[{ // For all champions
182 | key:String,
183 | statScore:Number,
184 | games:Number,
185 | winRate:Number,
186 | winRateChange:Number
187 | }],
188 | adcsupport:[{ // only support/ad
189 | key:String,
190 | statScore:Number,
191 | games:Number,
192 | winRate:Number,
193 | winRateChange:Number
194 | }],
195 | synergy:[{ // only support/ad
196 | key:String,
197 | statScore:Number,
198 | games:Number,
199 | winRate:Number,
200 | winRateChange:Number
201 | }]
202 | });
203 |
204 | module.exports = mongoose.model('WebChampionPage', webChampionPage);
--------------------------------------------------------------------------------
/models/web_champion_roles.js:
--------------------------------------------------------------------------------
1 | var mongoose = require('mongoose');
2 | /**
3 | * Used to build up the long champ list on the homepage and the
4 | * individual champion roles on the left hand side of the champion pages.
5 | */
6 | var webChampionRoles = new mongoose.Schema({
7 | key: String,
8 | name: String,
9 | lastUpdated: Number,
10 | roles:[{
11 | role:String,
12 | title:String,
13 | games:Number,
14 | percentPlayed:Number
15 | }]
16 | });
17 |
18 | module.exports = mongoose.model('WebChampionRoles', webChampionRoles);
--------------------------------------------------------------------------------
/models/web_home_page_summaries.js:
--------------------------------------------------------------------------------
1 | var mongoose = require('mongoose');
2 |
3 | var webHomePageSummaries = new mongoose.Schema({
4 | id: Number,
5 | data: [{
6 | title: String,
7 | total: Number,
8 | mostImproved:{
9 | key: String,
10 | name: String,
11 | difference: Number,
12 | overall: Number
13 | },
14 | leastImproved:{
15 | key: String,
16 | name: String,
17 | difference: Number,
18 | overall: Number
19 | },
20 | highestWinRate:{
21 | key: String,
22 | name: String,
23 | value: Number
24 | },
25 | lowestWinRate:{
26 | key: String,
27 | name: String,
28 | value: Number
29 | },
30 | bestOverall:{
31 | key: String,
32 | name: String,
33 | value: Number
34 | },
35 | worstOverall:{
36 | key: String,
37 | name: String,
38 | value: Number
39 | }
40 | }]
41 | });
42 |
43 | module.exports = mongoose.model('WebHomePageSummaries', webHomePageSummaries);
--------------------------------------------------------------------------------
/models/web_matchup_page.js:
--------------------------------------------------------------------------------
1 | var mongoose = require('mongoose');
2 |
3 | var webMatchupPage = new mongoose.Schema({
4 | champ1: {
5 | id: Number,
6 | key: String,
7 | name: String,
8 | role: String,
9 | roleTitle: String,
10 | performance: Number
11 | },
12 | champ2: {
13 | id: Number,
14 | key: String,
15 | name: String,
16 | role: String,
17 | roleTitle: String,
18 | performance: Number
19 | },
20 | role: String,
21 | dateAdded: Number,
22 | totalGames:Number,
23 | general: [{
24 | title: String,
25 | champ1:{
26 | val: Number,
27 | change: Number,
28 | score: Number //score to use is champ 1 is quering page
29 | },
30 | champ2:{
31 | val: Number,
32 | change: Number,
33 | score: Number //score to use if champ 2 is quering page
34 | },
35 | }],
36 | championMatrix:{
37 | labels:[String],
38 | champ1:[Number],
39 | champ2:[Number]
40 | },
41 | goldLength:{
42 | champ1:[Number],
43 | champ2:[Number]
44 | }
45 | });
46 |
47 | module.exports = mongoose.model('WebMatchupPage', webMatchupPage);
--------------------------------------------------------------------------------
/models/web_overall_role_data.js:
--------------------------------------------------------------------------------
1 | var mongoose = require('mongoose');
2 |
3 | var webOverallRoleData = new mongoose.Schema({
4 | role:String,
5 | totalNumber: Number,
6 | matrixLabels:[String],
7 | patchPlay: [Number]
8 | });
9 |
10 | module.exports = mongoose.model('WebOverallRoleData', webOverallRoleData);
--------------------------------------------------------------------------------
/models/web_overall_stats.js:
--------------------------------------------------------------------------------
1 | var mongoose = require('mongoose');
2 |
3 | var webOverallStats = new mongoose.Schema({
4 | patchHistory: [String],
5 | patch: String,
6 | championsAnalyzed: String,
7 | });
8 |
9 | module.exports = mongoose.model('WebOverallStats', webOverallStats);
--------------------------------------------------------------------------------
/models/web_statistics_page.js:
--------------------------------------------------------------------------------
1 | var mongoose = require('mongoose');
2 |
3 | var webStatisticsPage = new mongoose.Schema({
4 | key: String,
5 | title: String,
6 | role: String,
7 | general: {
8 | winPercent: Number,
9 | playPercent: Number,
10 | banRate: Number,
11 | experience: Number,
12 | kills: Number,
13 | deaths: Number,
14 | assists: Number,
15 | totalDamageDealtToChampions: Number,
16 | totalDamageTaken: Number,
17 | totalHeal: Number,
18 | largestKillingSpree: Number,
19 | minionsKilled: Number,
20 | neutralMinionsKilledTeamJungle: Number,
21 | neutralMinionsKilledEnemyJungle: Number,
22 | goldEarned: Number,
23 | overallPosition: Number,
24 | overallPositionChange: Number
25 | }
26 | });
27 |
28 | module.exports = mongoose.model('WebStatisticsPage', webStatisticsPage);
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "application-name",
3 | "version": "0.0.1",
4 | "private": true,
5 | "scripts": {
6 | "start": "node ./bin/www"
7 | },
8 | "dependencies": {
9 | "body-parser": "1.9.2",
10 | "compression": "1.2.0",
11 | "debug": "2.1.0 ",
12 | "ejs": "1.0.0",
13 | "express": "4.10.2",
14 | "mongoose": "3.8.19",
15 | "morgan": "1.5.0 ",
16 | "q": "1.4.1",
17 | "serve-favicon": "2.1.7"
18 | },
19 | "devDependencies": {
20 | "grunt": "~0.4.0",
21 | "grunt-contrib-cssmin": "*",
22 | "grunt-contrib-uglify": "*",
23 | "grunt-contrib-watch": "*",
24 | "grunt-contrib-concat": "*",
25 | "grunt-contrib-jshint": "*",
26 | "grunt-htmlhint": "*",
27 | "matchdep": "*"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/public/cpmstar/cpmstar_siteskin_iframebuster.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
2 | | Type | 6 |Average | 7 |Role Placement | 8 |Placement Change this patch | 9 |
|---|---|---|---|
| 15 | 16 | <%= championData.general[i].title %> 17 | 18 | | 19 | 20 |<%= championData.general[i].val %><% if(i < 3){ %>%<%}%> | 21 |22 | 23 | <%= championData.general[i].position %> 24 | 25 | / <%= generalRole.totalNumber %> 26 | | 27 |28 | 29 | 30 | <%- Math.abs(championData.general[i].change) %> | 31 |
| Overall Placement | 37 |<%= championData.overallPosition.position %> / <%= generalRole.totalNumber %> | 38 |39 | <%- Math.abs(championData.overallPosition.change) %> | 40 ||
6 |
7 | <% if (k!==5){ %>
8 | >
9 | <%}%>
10 | <% } %>
11 |
21 |
22 | <% if (l!==5){ %>
23 | >
24 | <%}%>
25 | <% } %>
26 |
6 |
7 | <% } %>
8 |
17 |
18 | <% } %>
19 |
9 |
24 |
38 | Champion.gg uses game data from Platinum to Challenger from NA, EUW, EUNE and Korea for the current patch, available through Riot's API 10 | 11 |
Most other LoL statistic websites are lacking in three areas. First, data doesn't necessarily reflect a champion's true performance if their play in certain roles isn't taken into account - this is something Champion.gg is very well equipped for; any champion can be selected in their played role to get tailored statistics.
13 |14 | Second, many statistical websites present their data over the past month/week/day. This gives an inaccurate view of the champion on the current patch. This is because the sample size can cover more than the current patch or be too small (in the case of a day). Champion.gg bases all data off the current patch apart from the player experience section - which uses the past 2 patches. 15 |
16 |17 | Third, many statistic websites don't show the win rates when a champion is (potentially) played at their best - Champion.gg provides win rates for the best builds, masteries, runes, summoners and skill order. 18 |
19 | 20 |22 | Thanks for asking! The overall performance ranking takes more than win rate into account! Depending on the particular role, different attributes (such as Win Rate, Play Rate, Ban Rate, Kills, Deaths, CS, Damage Dealt/Taken etc.) are weighted at different levels to provide an overview of how the champion performs as a whole. For example, an ADC champion has a higher weighting for 'Damage Dealt' than that of a support champion. 23 |
24 | 25 |27 | The statistical rating of counters is determined in a similar way as the overall performance ranking, but it also takes into account how well a champion normally performs, and the effect the particular matchup has on this performance. It also takes into account who has a stronger performance in the matchup. 28 |
29 | 30 |32 | Because the number of games where a full build is successfully completed is very low, it is hard to accurately determine the overall win rate of a given build. This is because completed builds typically have extremely high win rates (players that are ahead have more items completed). 33 |
34 |35 | Therefore, Champion.gg places a similar weighting for partially completed builds that follow the same build path as the full build. This helps provide a better overview of the build as a whole as it takes into account all stages of the build. In order to further stabilize the win rate, it is normalized against the win rate of the champions role. 36 |
37 | 38 | 39 |43 | Champion.gg uses Riot's API which provides the lane and role of a particular champion. This is based on the areas a particular champion spends the majority of the early game/laning phase. 44 |
45 | 46 |48 | Data is updated as soon as possible whenever a new patch is released (usually within 3 days). Towards the end of a patch, data is updated less frequently--Champion.gg has over 300gb of champion data, so processing can take around 15 hours. 49 |
50 | 51 |53 | Champions such as Urgot are seen very very rarely in Platinum+ games. Consequently, there isn't always a large enough sample size to determine whether the statistics are a true reflection of the champion's performance. If small sample size isn't an issue, chances are Riot is having balancing issues. 54 |
55 | 56 |58 | Champion.gg is and always will be free to use - it does, however, cost to process, download, and host gigabytes of data each day. There are a number of ways you can help out! You can share Champion.gg with your friends/groups, you can white list Champion.gg through your adblocker, or for those who don't like advertisements, you can consider donating. 59 |
60 | 61 |63 | I have the web development/design side of Champion.gg on GitHub - You can take a look for yourself! The data aggregation/processing side of things is in a private repo until I clean it up. 64 |
65 | 66 |68 | Champion.gg is a full JavaScript endeavour, utilising Node.js/Express on the back end with MongoDB serving the data. The front end uses Angular.js as its primary framework. Data aggregation/analysis was performed with MongoDB's aggregation framework / Node.js. 69 |
70 | 71 |73 | Send me a message on Reddit at /u/joeldo, through the Champion.gg Facebook page or GitHub 74 |
75 |