diff --git a/src/oastat_static_web_generator.cpp b/src/oastat_static_web_generator.cpp index 0ba870e..a5d1e04 100644 --- a/src/oastat_static_web_generator.cpp +++ b/src/oastat_static_web_generator.cpp @@ -247,6 +247,91 @@ void write_html_game(cppdb::session& database, const OastatGame& game) { myfile.close(); } +std::string getWeaponName(int modtype) { + switch(modtype) { + case MOD_SHOTGUN: return "Shotgun"; + case MOD_GAUNTLET: return "Gauntlet"; + case MOD_MACHINEGUN: return "Machinegun"; + case MOD_GRENADE: + case MOD_GRENADE_SPLASH: return "Grenade"; + case MOD_ROCKET: + case MOD_ROCKET_SPLASH: return "Rocket"; + case MOD_PLASMA: + case MOD_PLASMA_SPLASH: return "Plasma"; + case MOD_RAILGUN: return "Railgun"; + case MOD_LIGHTNING: return "Lightning"; + case MOD_BFG: + case MOD_BFG_SPLASH: return "BFG"; + case MOD_NAIL: return "Nailgun"; + case MOD_CHAINGUN: return "Chaingun"; + case MOD_TELEFRAG: return "Telefrag"; + case MOD_FALLING: return "Falling"; + default: return "Other"; + } +} + +void getMapWeaponKills(cppdb::session& database, const std::string& mapname, std::map& weapon_kills) { + std::string sql = "select k.modtype, count(0) c from oastat.oastat_kills k, oastat.oastat_games g " + "where g.gamenumber = k.gamenumber and g.mapname = ? and k.attacker <> k.target " + "group by k.modtype order by c desc"; + cppdb::statement st = database.prepare(sql); + st.bind(1, mapname); + cppdb::result res = st.query(); + while(res.next()) { + int modtype; + int count; + res >> modtype >> count; + weapon_kills[modtype] = count; + } +} + +void getMapRecentGames(cppdb::session& database, const std::string& mapname, std::vector& games) { + std::string sql = "select gamenumber, gametype, mapname, time, basegame, second, servername " + "from oastat.oastat_games where mapname = ? order by gamenumber desc limit 10"; + cppdb::statement st = database.prepare(sql); + st.bind(1, mapname); + cppdb::result res = st.query(); + while(res.next()) { + OastatGame game; + res >> game.gamenumber >> game.gametype >> game.mapname >> game.time >> game.basegame >> game.second >> game.servername; + games.push_back(game); + write_html_game(database, game); + } +} + +void write_html_map(cppdb::session& database, const std::string& mapname) { + ctemplate::TemplateDictionary map_tpl("templates/map.tpl"); + map_tpl.SetValue("GENERATION_DATE", timestamp_now_as_string(database)); + map_tpl.SetValue("MAP_NAME", mapname); + + // Get weapon kills for this map + std::map weapon_kills; + getMapWeaponKills(database, mapname, weapon_kills); + for (const auto& wk : weapon_kills) { + ctemplate::TemplateDictionary* sub_dict = map_tpl.AddSectionDictionary("WEAPON_KILLS"); + sub_dict->SetValue("WEAPON_NAME", getWeaponName(wk.first)); + sub_dict->SetValue("KILL_COUNT", std::to_string(wk.second)); + } + + // Get recent matches for this map + std::vector games; + getMapRecentGames(database, mapname, games); + for (size_t i = 0; i < games.size(); ++i) { + const OastatGame& game = games[i]; + ctemplate::TemplateDictionary* sub_dict = map_tpl.AddSectionDictionary("RECENT_MATCHES"); + sub_dict->SetValue("GAMENUMBER", std::to_string(game.gamenumber)); + sub_dict->SetValue("TIME", getTimeStamp(game.time)); + sub_dict->SetValue("SERVERNAME", game.servername); + } + + std::string output; + ctemplate::ExpandTemplate("templates/map.tpl", ctemplate::DO_NOT_STRIP, &map_tpl, &output); + std::ofstream myfile; + myfile.open (cmdargs.output_dir+"/map/"+mapname+".html"); + myfile << output; + myfile.close(); +} + void write_html_index(cppdb::session& database) { ctemplate::TemplateDictionary index_tpl("templates/index.tpl"); index_tpl.SetValue("GENERATION_DATE", timestamp_now_as_string(database)); @@ -320,6 +405,11 @@ void write_html_index(cppdb::session& database) { void write_files(cppdb::session& database) { write_html_index(database); + // Generate map pages + std::vector map_list = get_most_played_maps(database); + for (const std::string& mapname : map_list) { + write_html_map(database, mapname); + } } @@ -367,6 +457,7 @@ int main(int argc, const char* argv[]) { write_current_time(database); create_dir_recursive(cmdargs.output_dir+"/static"); create_dir_recursive(cmdargs.output_dir+"/game"); + create_dir_recursive(cmdargs.output_dir+"/map"); copy_static_files("static_content", cmdargs.output_dir+"/static"); write_files(database); return 0; diff --git a/templates/index.tpl b/templates/index.tpl index 8724ced..12bf57f 100644 --- a/templates/index.tpl +++ b/templates/index.tpl @@ -114,7 +114,7 @@ {{#MAP_LIST}} - {{MAP_NAME}} + {{MAP_NAME}} {{TIMES_PLAYED}} {{LAST_PLAYED}} diff --git a/templates/map.tpl b/templates/map.tpl new file mode 100644 index 0000000..8e50aa2 --- /dev/null +++ b/templates/map.tpl @@ -0,0 +1,77 @@ +{{%AUTOESCAPE context="HTML"}} + +{{! + Copyright (c) 2019 Poul Sander + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +}} + + + + + + + + OpenArena Stats - Map {{MAP_NAME}} + + +
+

Map: {{MAP_NAME}}

+ +
+ {{MAP_NAME}} +
+ +

Weapon Kills on this Map

+ + + + + + {{#WEAPON_KILLS}} + + + + + {{/WEAPON_KILLS}} +
WeaponKills
{{WEAPON_NAME}}{{KILL_COUNT}}
+ +

Most Recent Matches

+ + + + + + + {{#RECENT_MATCHES}} + + + + + + {{/RECENT_MATCHES}} +
GamePlayed atServer name
{{GAMENUMBER}}{{TIME}}{{SERVERNAME}}
+ +

Back to main page

+

Last updated on {{GENERATION_DATE}}

+
+ +