AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Unapproved Plugins (https://forums.alliedmods.net/forumdisplay.php?f=109)
-   -   Map Rate v0.10 (6/30) (https://forums.alliedmods.net/showthread.php?t=69593)

FLOOR_MASTER 04-07-2008 08:29

Map Rate v0.10 (6/30)
 
3 Attachment(s)
Map Rate was written in response to a request in the Plugin Requests Forum. Its purpose is to allow players to rate a map between 1-5, inclusive, and view the current rating. Naturally, you will probably want to write some sort of external tool that makes use of the data gathered outside of the game. I certainly will be...

Configuration
  • maprate_db_config (default "default")
    • Specifies what configuration in addons/sourcemod/configs/database.cfg to use to connect to a MySQL or SQLite DB.
  • maprate_allow_revote (default "1")
    • When non-zero, this allows players to change their existing map rating (recommended). When zero, players cannot rate a map more than once.
  • maprate_autorate_time (default "0")
    • When non-zero, this specifies the time to wait since the player started playing the map before automatically asking the player to rate the map when they die (and only if they haven't rated the map before). For example, if maprate_autorate_time is 180, the plugin will start asking players who die to rate the map 3 minutes after the player starts playing the map. The behavior of this cvar was changed in v0.10.
  • maprate_autorate_delay (default "5")
    • When maprate_autorate_time is enabled, Map Rate will wait maprate_autorate_delay seconds after a player dies before asking them to rate the map. This is useful if you have another plugin that displays information to a player when they die (e.g. stats) that could interfere with Map Rate.
  • maprate_table (default "map_ratings")
    • The name of the database table to store map ratings in. If you run multiple servers, you may want to change this for different game types or for individual servers, depending on whether you servers share databases and whether you want maprating data shared across multiple servers.
  • maprate_dismiss (default "0")
    • If non-zero, a "Dismiss" option will be added to the menu as option #1 (instead of "1 Star"). Changes to this cvar take effect on every map change, not instantly.
  • maprate_autoresults (default "1")
    • If non-zero, the graph of a map's rating are automatically displayed to a player after the player rates a map.
CommandsAlso accessible via the admin menu is the "Have All Players Rate This Map" command:
http://www.2fort2furious.com/images/..._adminmenu.png

Clients will see this:
http://www.2fort2furious.com/images/...menuclient.png

This command requires the vote admin flag ("k").

Database Schema
For those who will develop their own tools to use the data this plugin collects, here's what you need to know. This information is only valid if you're using MySQL as your database driver.
Code:

CREATE TABLE IF NOT EXISTS map_ratings (
  steamid VARCHAR(24),
  map VARCHAR(48),
  rating INT(4),
  rated DATETIME,
  UNIQUE KEY (map, steamid)
);

As you can see, it's very simple. The one thing I can envision coders wanting is a field for player name, but that's trickier to track and IMO outside the scope of this plugin.

PHP Viewer (new 2008-05-22)
I wrote up a little PHP app to display the results. Just modify the top DEFINEs as needed. Here's what it looks like:

http://www.2fort2furious.com/images/map_ratings.png

And here's the code (This is for PHP5. If you have PHP4, look elsewhere in this thread for a compatible version):

PHP Code:

<?php

/**
 * Map Rate Viewer
 * Copyright 2008 Ryan Mannion. All Rights Reserved.
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

define('MR_DBHOST''localhost');
define('MR_DBUSER''username');
define('MR_DBPASS''password');
define('MR_DBNAME''sourcemod_db_name');
define('MR_TABLENAME''map_ratings');
define('MR_THRESHOLD'0);
define('MR_COLUMNS'3);
define('MR_LEFTWIDTH'200);
define('MR_RIGHTWIDTH'100);

$sort = (isset($_GET['sort']) ? $_GET['sort'] : 'rating');
$reverse = (isset($_GET['reverse']) ? $_GET['reverse'] : 'no');
?>
<html>
<head>
    <style type="text/css">
        body {
            font-family: Trebuchet MS, Helvetica, sans-serif;
            margin-left: auto;
            margin-right: auto;
            width: <?php echo MR_COLUMNS * (MR_LEFTWIDTH MR_RIGHTWIDTH); ?>;
        }

        div.title {
            margin: 0px;
            padding: 10px;
            color: white;
            background-color: #000066;;
        }
        div.title span.title {
            font-weight: bold;
            font-size: 18pt;
        }

        div.title a, a:visited, a:hover, a:link {
            color: white;
        }

        div.ratings {
        }

        table.map_rating {
            border: 2px solid DarkBlue;
            background-color: white;
            margin: 0;
        }

        table.map_rating span.map_name {
            font-weight: bold;
        }

        table.rating_graph {
            background-color: Lavender;
        }
        table.rating_graph td {
            font-size: 10pt;
        }
        table.rating_graph tr.bars td {
            vertical-align: bottom;
        }
        table.rating_graph tr.labels td {
            text-align: center;
            font-weight: bold;
            font-size: 8pt;
        }
        table.rating_graph div.rating_1 {
            background-color: #B80000;
        }
        table.rating_graph div.rating_2 {
            background-color: #B85800;
        }
        table.rating_graph div.rating_3 {
            background-color: #B89800;
        }
        table.rating_graph div.rating_4 {
            background-color: #99CC33;
        }
        table.rating_graph div.rating_5 {
            background-color: #33CC00;
        }
    </style>

</head>
<body>

<?php
class MapRating {
    public 
$name;
    public 
$num_ratings 0;
    public 
$ratings = array(=> 0=> 0=> 0=> 0=> 0);
    private 
$max_ratings 0;

    function 
__construct($name) {
        
$this->name $name;
    }

    function 
add_rating($rating$count) {
        if (!isset(
$this->ratings[$rating])) {
            throw new 
Exception('Invalid rating');
        }
        
$this->ratings[$rating] += $count;
        
$this->num_ratings += $count;
        
$this->max_ratings max($this->max_ratings$count);
    }

    function 
get_graph($width 300$height 100) {
        
$row_bars = array();
        
$row_labels = array();
        for (
$i 1$i <= 5$i++) {
            
/* The weird comment inside the DIV is a fix for IE which renders
             * 20px height minimum without the comment */
            
array_push($row_bars
                
"\t\t<td width=\"20%\"><div class=\"rating_$i\" style=\"height: "
                
.$this->get_rating_height($i$height)
                .
"\"><!-- --></div></td>\n"
            
);
            
array_push($row_labels"\t\t<td>{$this->ratings[$i]}</td>\n");
        }

        
        return 
"<table class=\"rating_graph\" width=\"$width\" height=\"$height\">\n".
            
"\t<tr class=\"bars\">\n".implode($row_bars)."\t</tr>\n".
            
"\t<tr class=\"labels\" height=\"15\">\n".implode($row_labels)."\t</tr>\n".
            
"</table>\n";
    }

    function 
get_average() {
        if (
$this->num_ratings) {
            
$rating_sum 0;
            foreach (
array_keys($this->ratings) as $key) {
                
$rating_sum += $key $this->ratings[$key];
            }
            return 
round($rating_sum $this->num_ratings2);
        }
        else {
            return 
0;
        }
    }

    private function 
get_rating_height($rating$height) {
        if (
$this->max_ratings) {
            return (int)(
$this->ratings[$rating] / $this->max_ratings $height);
        }
        else {
            return 
$height;
        }
    }

    function 
get_num_ratings() {
        return 
"{$this->num_ratings} rating".($this->num_ratings == '' 's');
    }

    function 
get_table() {
        return 
"<table class=\"map_rating\">\n"
            
."\t<tr>\n"
            
."\t\t<td width=\"".MR_LEFTWIDTH."\"><span class=\"map_name\">{$this->name}</span><br/>{$this->get_average()} "
            
."({$this->get_num_ratings()})</td>\n"
            
."\t\t<td>{$this->get_graph(MR_RIGHTWIDTH30)}</td>\n"
            
."\t</tr>\n"
            
."</table>\n";
    }
}

class 
MapRatings {
    private 
$map_ratings;
    private 
$maps;
    private 
$db;

    function 
__construct() {
        
$this->db mysql_pconnect(MR_DBHOSTMR_DBUSERMR_DBPASS);
        if (!
$this->db|| !mysql_select_db(MR_DBNAME)) {
            throw new 
Exception('Could not establish connection to the database');
        }
        
$this->populate_ratings();
    }

    private function 
populate_ratings() {
        
$sort 'ORDER BY rating DESC';
            
$query 'SELECT map, rating, COUNT(*) AS count FROM '.MR_TABLENAME.' GROUP BY map, rating';
            
$result mysql_query($query);

        
$this->map_ratings = array();
        while (
$row mysql_fetch_object($result)) {
            if (!isset(
$this->map_ratings[$row->map])) {
                
$this->map_ratings[$row->map] = new MapRating($row->map);
            }
            
$this->map_ratings[$row->map]->add_rating($row->rating$row->count);
        }

        foreach (
array_keys($this->map_ratings) as $key) {
            if (
$this->map_ratings[$key]->num_ratings MR_THRESHOLD) {
                unset(
$this->map_ratings[$key]);
            }
        }

        
$this->maps array_keys($this->map_ratings);
    }

    function 
get_links($sort='name'$dir='no') {
        
$sort_types = array('rating' => 'Rating''name' => 'Map Name''ratings' => 'Number of Ratings');

        
$links = array();
        foreach (
array_keys($sort_types) as $sort_type) {
            
$link '';
            if (
$sort_type == $sort) {
                
$link "<strong>{$sort_types[$sort_type]}</strong>";
            }
            else {
                
$link "<a href=\"{$_SERVER['PHP_SELF']}?sort=$sort_type\">{$sort_types[$sort_type]}</a>";
            }
            
array_push($links$link);
        }

        return 
'<strong>Order By: </strong>'.implode(' | '$links);
    }

    function 
set_sort($sort='rating'$dir='no') {
        
$rating = array();
        
$ratings = array();
        foreach (
array_values($this->map_ratings) as $mr) {
            
array_push($rating$mr->get_average());
            
array_push($ratings$mr->num_ratings);
        }
        if (
$sort == "name") {
            
sort($this->maps);
        }
        else if (
$sort == "rating") {
            
array_multisort($ratingSORT_DESC$this->maps);
        }
        else if (
$sort == "ratings") {
            
array_multisort($ratingsSORT_DESC$this->maps);
        }

        if (
$dir == "yes") {
            
$this->maps array_reverse($this->maps);
        }
    }

    function 
get_ratings_table() {
        
ob_start();
        echo 
"<table>\n";
            
$cell 0;
            echo 
"\t<tr>\n";
        foreach (
$this->maps as $map) {
            
$mr $this->map_ratings[$map];
            if (!
$cell) {
                echo 
"\t</tr>\n";
                echo 
"\t<tr>\n";
            }
            echo 
"\t\t<td>".$mr->get_table()."</td>\n";
            
$cell = ($cell 1) % MR_COLUMNS;
        }
        while (
$cell) {
            echo 
"\t\t<td>&nbsp;</td>\n";
            
$cell = ($cell 1) % MR_COLUMNS;
        }
        echo 
"\t</tr>\n";
        echo 
"</table>\n";

        
$table ob_get_contents();
        
ob_end_clean();
        return 
$table;
    }
}

$mr = new MapRatings();
echo 
"<div class=\"title\"><span class=\"title\">Map Ratings</span><br/>";
echo 
"<span class=\"links\">".$mr->get_links($sort$reverse)."</span></div>\n";
echo 
"<div class=\"ratings\">\n";
$mr->set_sort($sort$reverse);
echo 
$mr->get_ratings_table();
echo 
"</div>\n";

?>
</body>
</html>

Notes about maprate.php
  • Use MR_THRESHOLD to specify a minimum number of ratings for a map to appear
  • If there's a map with a long name, increase MR_LEFTWIDTH
  • MR_COLUMNS sets the number of columns to organize the maps into
Version History
  • 2008-04-07 - v0.1
    • Initial release
  • 2008-04-07 - v0.2
    • Added support for SQLite
  • 2008-04-07 - v0.3
    • Added AdminMenu support
    • Renamed !rate and !rating commands to !maprate and !maprating, respectively.
  • 2008-04-09 - v0.4
    • Added AutoRate (via maprate_autorate_time) for automatically asking dead players to rate the map after a certain period of time
    • Added ability to disallow re-rating a map
    • Added admin command to delete ratings for the current map
  • 2008-04-10 - v0.5
    • Added cvar maprate_database
    • Fixed minor bug involving recognizing cvar settings when the server is first launched
  • 2008-04-10 - v0.6
    • Added in-game rating viewing tools
  • 2008-04-11 - v0.7
    • Fixed a memory leak
  • 2008-05-17 - v0.8
    • Added internationalization support
    • Added maprate_autorate_delay cvar
  • 2008-05-19
    • Added German translations to maprate.phrases.txt. Thank you to st0rm_r1der for providing the German translations.
  • 2008-05-22
    • Added maprate.php, a PHP frontend for viewing map ratings
  • 2008-05-24 - v0.9
    • Fixed autorate bug involving players disconnecting immediately after being killed
  • 2008-06-30 - v0.10
    • Changed behavior of maprate_autorate_time to be based on when each player connected rather than when the map started
    • Added maprate_dismiss
    • Added "Dismiss" section to maprate.phrases.txt
    • Added maprate_autoresults
Installation
  • Copy maprate.smx to addons/sourcemod/scripting/
  • Copy maprate.phrases.txt to addons/sourcemod/translations/
Note: I whipped this up in about an hour without looking at existing, non-SourceMod map rating plugins, so I don't know if it behaves similarly to what one would expect from a plugin of this type. Also, this plugin was tested on a TF2 server. Please let me know if you experience problems with other mods.

In v0.10, maprate.phrases.txt was updated. You MUST update it or maprate_dismiss will not work.

Spitfire20 04-07-2008 08:50

Re: Map Rate
 
Just what i Needed!!

Can this be modded so it automatically appears say 5 minutes before the next map ?

What would i need for the results to be shown on a website/webpage?

or what Extreme Said , So we can see them Ingame :P

Extreme_One 04-07-2008 09:19

Re: Map Rate
 
Can this work with a SQLite database?

I'd be happy enough with being able to view ratings from in-game.

symphyle 04-07-2008 11:03

Re: Map Rate
 
Yeah ! Good Work :)
I'll test this week :)

FLOOR_MASTER 04-07-2008 12:25

Re: Map Rate
 
Quote:

Originally Posted by Extreme_One (Post 607747)
Can this work with a SQLite database?

I'd be happy enough with being able to view ratings from in-game.

I posted an update (v0.2) with support for SQLite.

I'll work on some method of displaying the full results in-game.

Spitfire20: what game are you running?

Spitfire20 04-07-2008 12:59

Re: Map Rate
 
TF2 Mate - Read ur PMS 2 :P

OziOn 04-07-2008 13:06

Re: Map Rate
 
I think it would be useful, if admins could decide when to start a map rate, from the admin menu perhaps, so that all players on the server would be asked to rate a map at the same time.

Spitfire20 04-07-2008 14:26

Re: Map Rate
 
On The Map Rating Can it be something Like

Map : cp_badlannds
Please Vote the Map

1 - Terrible
2 - Poor
3 - Average
4 - Good
5 - Execllent

Then Once they have Voted

You Have voted cp_badlands as "Good"

Whole Map voting for whole server is 59% , if the Whole Vote Drops below 70% the map gets disabled so the server does not play it until a admin reactivates it ?

tcviper 04-07-2008 14:49

Re: Map Rate
 
Finally, thanks for this amazing plugin, very usefull!

tcviper 04-07-2008 14:52

Re: Map Rate
 
What about making the server cycle through the higher rated maps automatically?


All times are GMT -4. The time now is 10:50.

Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.