NexgenStatsViewer105 - depreciated code for 'getstats.php' (php7)

Discussions about Coding and Scripting
User avatar
StalkS
Novice
Posts: 10
Joined: Fri May 07, 2021 3:26 pm
Personal rank: =-5t4lk3rZ=-

NexgenStatsViewer105 - depreciated code for 'getstats.php' (php7)

Post by StalkS »

Hi, I am trying to get the 'Nexgen Statistics Viewer Plugin' to work with a UTStats server that is running on php7.

It appears some of the code has depreciated and getstats.php is incompatible in its current form.

I ran the code through the PHP Code Checker https://phpcodechecker.com/ and changed all of the depreciated functions with their php7 alternatives (see below)

Code: Select all

<?php

/***************************************************************************************************
 *
 *  Nexgen statistics viewer by Zeropoint.
 *
 *  $FILE         getstats.php
 *  $VERSION      1.01 (27-6-2008 18:36)
 *  $AUTHOR       Daan 'Defrost' Scheerens  initial version
 *  $CONTACT      d.scheerens@gmail.com
 *  $DESCRIPTION  The server side script that provides an interface for the Nexgen statistics viewer
 *                plugin and UTStats.
 *
 **************************************************************************************************/

/***** CONSTANTS *****/
define('MAX_NUMBER_OF_LISTS', 5);
define('MAX_NUMBER_OF_PLAYERS', 30);



/***** CONFIG *****/

// List settings.
add_player_list('localhost', 'Private', 'Private', 'Private', 'Tournament DeathMatch', 5, 'Top DM players');
//add_player_list('db_host2', 'db_name2', 'db_user2', 'db_password2', 'Capture the Flag', 5, 'Top CTF players');
//add_player_list('db_host3', 'db_name3', 'db_user3', 'db_password3', 'Assault', 5, 'Top AS players');




/***** MAIN *****/

// Initialze.
$last_db_host = '';
$last_db_name = '';
$last_db_user = '';
$db_link = false;

// For each player list...
$player_list_index = 0;
$player_count = 0;
while ($player_list_index < sizeof($player_lists) &&
       $player_list_index < MAX_NUMBER_OF_LISTS &&
       $player_count < MAX_NUMBER_OF_PLAYERS) {
	
	// Connect to database.
	$curr_db_host = $player_lists[$player_list_index]['db_host'];
	$curr_db_name = $player_lists[$player_list_index]['db_name'];
	$curr_db_user = $player_lists[$player_list_index]['db_user'];
	$curr_db_password = $player_lists[$player_list_index]['db_password'];
	if ($curr_db_host != $last_db_host ||
	    $curr_db_user != $last_db_user) {
		if ($db_link) {
			mysqli_close($db_link);
		}
		$db_link = mysqli_connect($curr_db_host, $curr_db_user, $curr_db_password) or die('unable to connect to database, '.mysqli_error());
		mysqli_select_db($curr_db_name) or die('could not select database, '.mysqli_error());
	} else if ($curr_db_name != $curr_db_host) {
		mysqli_select_db($curr_db_name) or die('could not select database, '.mysqli_error());
	}
	$last_db_host = $curr_db_host;
	$last_db_name = $curr_db_name;
	$last_db_user = $curr_db_user;
	
	// Get list details.
	$game_name = $player_lists[$player_list_index]['game_name'];
	$num_players = $player_lists[$player_list_index]['num_players'];
	$list_title = $player_lists[$player_list_index]['list_title'];
	
	// Retrieve game id.
	$query = "select id from uts_games where name = '".mysqli_real_escape_string($game_name)."' limit 1";
	$result = mysqli_query($query);
	if ($r = mysqli_fetch_array($result)) {
		$game_id = $r['id'];
	} else {
		$game_id = 0;
	}
	
	// Get player list.
	if ($game_id > 0) {
		$query = "select pid, rank, prevrank from uts_rank where gid = $game_id order by rank desc limit $num_players";
		$result = mysqli_query($query);
		if (mysqli_num_rows($result) > 0) {
			println('beginlist "'.str_replace('"', '\\"', $list_title).'"');
		}
		while (($r = mysqli_fetch_array($result)) && $player_count < MAX_NUMBER_OF_PLAYERS) {
			// Get player rank info.
			$player_id = $r['pid'];
			$rank = $r['rank'];
			$previous_rank = $r['prevrank'];
			
			// Get player info.
			$query = "select name, country from uts_pinfo where id = $player_id limit 1";
			$result2 = mysqli_query($query);
			$r2 = mysqli_fetch_array($result2);
			$player_name = $r2['name'];
			$player_country = $r2['country'];
			mysqli_free_result($result2);
			if (substr($player_name, -1) == '\\') {
				$player_name .= ' ';
			}
			
			// Process data.
			if ($rank > $previous_rank) {
				$rank_change = 'up';
			} else if ($rank < $previous_rank) {
				$rank_change = 'down';
			} else {
				$rank_change = 'nc';
			}
			
			// Echo player info.
			println('addplayer "'.str_replace('"', '\\"', $player_name).'" '.round($rank).' '.$player_country.' '.$rank_change);
			
			// Continue with next player.
			$player_count++;
		}
		
		mysqli_free_result($result);
	}
	
	// Continue with next list.
	$player_list_index++;
}

// End of execution, no more output is desired!
die();



/***** FUNCTIONS *****/

/***************************************************************************************************
 *
 *  $DESCRIPTION  Adds a new player list that will be displayed on the server.
 *  $PARAM        $game_name    The name of the game type.
 *  $PARAM        $num_players  Number of players to display in the list.
 *  $PARAM        $list_title   Display title of the list on server.
 *
 **************************************************************************************************/
function add_player_list($db_host, $db_name, $db_user, $db_password, $game_name, $num_players = 10, $list_title = '') {
	global $player_lists;
	
	if (trim($list_title) == '') {
		$list_title = $game_name;
	}
	
	$player_lists[] = array('game_name' => $game_name,
	                        'num_players' => $num_players,
	                        'list_title' => $list_title,
	                        'db_host' => $db_host,
	                        'db_name' => $db_name,
	                        'db_user' => $db_user,
	                        'db_password' => $db_password);
}



/***************************************************************************************************
 *
 *  $DESCRIPTION  Writes a line to the output.
 *  $PARAM        $text  The text that is to be written.
 *
 **************************************************************************************************/
function println($text) {
	echo $text."\r\n";
}
?>
It now responds when called from my UTStats webpage, but always gives the error 'could not select database,' But I have used the exact details that are in the UTstats config. I am out of my depth now and at a loss at how to resolve this, and I am hoping that maybe a member of the community can help amend the code for php7?

Also posted on dscheerens /nexgen github pagehttps://github.com/dscheerens/nexgen/issues/1


Anyway, all the best, & fingers crossed.
User avatar
Feralidragon
Godlike
Posts: 5477
Joined: Wed Feb 27, 2008 6:24 pm
Personal rank: Work In Progress
Location: Liandri

Re: NexgenStatsViewer105 - depreciated code for 'getstats.php' (php7)

Post by Feralidragon »

What's the exact complete error message?

From what I can tell from the code, the exact MySQL error is concatenated to the error message you're mentioning, so you should be getting more details about what exactly fails when the database is being selected, and it's generally self-explanatory (it may say something like the database not existing, or the user not having permissions to access that database, etc), and may turn out to be a database configuration issue, and not an issue with the PHP code.

But more details are needed regardless to confirm what the problem might be.
Buggie
Godlike
Posts: 1921
Joined: Sat Mar 21, 2020 5:32 am

Re: NexgenStatsViewer105 - depreciated code for 'getstats.php' (php7)

Post by Buggie »

You can not simple blindly replace mysql_* functions to mysqli_* if previous code not use variable for store link id. In such case you need introduce it.
mysqli_select_db required two parameters: link id, database name.
mysqli_error required one parameter: link id.
When you fail to connect need use mysqli_connect_error instead of mysqli_error.

Code: Select all

		$db_link = mysqli_connect($curr_db_host, $curr_db_user, $curr_db_password) or die('unable to connect to database, '.mysqli_error());
		mysqli_select_db($curr_db_name) or die('could not select database, '.mysqli_error());
Must be:

Code: Select all

		$db_link = mysqli_connect($curr_db_host, $curr_db_user, $curr_db_password) or die('unable to connect to database, '.mysqli_connect_error());
		mysqli_select_db($db_link, $curr_db_name) or die('could not select database, '.mysqli_error($db_link));
In general you need walk around each mysqli_* function, look for it proper usage on https://www.php.net/manual/en/mysqli.connect-error.php
and correct it.
You need "procedural style".
Also pay attention to parameters order, because in some cases mysql_ and mysqli_ use different order of passed parameters. Do not rely only of count it.
ShaiHulud
Adept
Posts: 446
Joined: Sat Dec 22, 2012 6:37 am

Re: NexgenStatsViewer105 - depreciated code for 'getstats.php' (php7)

Post by ShaiHulud »

I remember someone advertising an updated version a while ago - it may have been someone from Passionate Gaming (https://discord.com/channels/2773524765 ... 1077225522), but I can't seem to find details of that now - that link points to their Technical Support area, though, so it might be worth asking there (they're running a version here: http://stats.ut99pg.com/)
User avatar
StalkS
Novice
Posts: 10
Joined: Fri May 07, 2021 3:26 pm
Personal rank: =-5t4lk3rZ=-

Re: NexgenStatsViewer105 - depreciated code for 'getstats.php' (php7)

Post by StalkS »

Thank you Feralidragon, Buggie & ShaiHulud


@Feralidragon, Apologies as stated while I can set up servers etc. by following the readme's etc. I do not have much linux / PHP authoring experience. Which log files should I be looking for to help decipher the error?

@Buggie, Thank you for the pointers - I will invest some time and see if I can rewrite the script- I am not a coder in away shape or form, but have managed to successfully 'bodge' a few things in the past - (hence having a crack at running the code through the checker and trying my luck).

@ShaiHulud, Thank you - that would certainly be fantastic if it exists already - I will reach out and ask.

All the best

StalkS
User avatar
UT Sniper (SJA94)
Masterful
Posts: 727
Joined: Thu Jun 24, 2010 10:35 pm
Personal rank: noob programmer
Location: England

Re: NexgenStatsViewer105 - depreciated code for 'getstats.php' (php7)

Post by UT Sniper (SJA94) »

I made a quick version to work with php7.
Also made it so you can choose a display title instead of just the gametype name.

Download:
https://github.com/scottadkin/ut-nexgen ... es/tag/1.0

Github:
https://github.com/scottadkin/ut-nexgen ... iewer-php7


Source:

Code: Select all

<?php

new NexgenPlayerList("localhost", "utstats", "root", "", "Test Title", "Capture the Flag (Insta)", 5);
//new NexgenPlayerList("localhost", "database", "user", "password", "Another Title that's boring", "Tournament Deathmatch (Insta)", 22);
//new NexgenPlayerList("localhost", "database", "user", "password", "Another Title that's boring", "Tournament Deathmatch (Insta)", 3);


const MAX_PLAYERS = 30;
const MAX_LISTS = 5;


$totalPlayers = 0;
$totalLists = 0;


class NexgenPlayerList{

    public function __construct($host, $database, $user, $password, $title, $gametype, $totalPlayers){

        $this->host = $host;
        $this->database = $database;
        $this->user = $user;
        $this->password = $password;
        $this->title = $title;
        $this->gametype = $gametype;
        $this->totalPlayers = $totalPlayers;

        $this->playerIds = [];
        $this->rankings = [];

        $this->players = [];

        $this->connect();
        $this->setGameId();

        if(isset($this->gametypeId)){

            $this->setRankingData();
            $this->setPlayerData();
            $this->print();
        }
    }


    private function connect(){

        $this->db = new mysqli($this->host, $this->user, $this->password, $this->database);

        if($this->db->connect_errno){
            echo "Failed to connect to database<br/>";
            echo $this->db->connect_error;
            die();
        }
    }

    private function setGameId(){



        $query = "SELECT `id` FROM `uts_games` WHERE `name`=? LIMIT 1";

        if($stmt = $this->db->prepare($query)){
            $stmt->bind_param("s", $this->gametype);
            $stmt->execute();
            $result = $stmt->get_result();

            $d = $result->fetch_assoc();
    
            if(isset($d['id'])){
                $this->gametypeId = $d['id'];
            }

            $stmt->close();

        }else{
            echo $this->db->error;
        }
        
    }

    private function setRankingData(){

        $query = "SELECT `pid`,`rank`,`prevrank` FROM uts_rank WHERE `gid`=? ORDER BY `rank` DESC LIMIT ?";

        if($stmt = $this->db->prepare($query)){
            $stmt->bind_param("dd", $this->gametypeId, $this->totalPlayers);
            $stmt->execute();
            $result = $stmt->get_result();

            while($d = $result->fetch_assoc()){

                $this->rankings[] = $d;
                $this->playerIds[] = $d['pid'];
            }

            $stmt->close();

        }else{
            echo $this->db->error;
        }
    }

    private function setPlayerData(){

        $qMarks = "";
        $paramLetters = "";

        $totalPlayers = count($this->playerIds);

        if($totalPlayers === 0) return;



        for($i = 0; $i < $totalPlayers; $i++){

            $qMarks.= "?";

            $paramLetters.="s";

            if($i < $totalPlayers - 1){
                $qMarks.=",\n";
            }
        }

        $query = "SELECT `id`,`name`,`country` FROM uts_pinfo WHERE `id` in(".$qMarks.")";

        if($stmt = $this->db->prepare($query)){

            $stmt->bind_param($paramLetters, ...$this->playerIds);
            $stmt->execute();
            $result = $stmt->get_result();

            while($d = $result->fetch_assoc()){

                $this->players[$d['id']] = $d;
            }

            $stmt->close();

          

        }else{

            echo $this->db->error;
        }

    }

    private function print(){

        $find = ["\"","\\"];
        $replace = ["",""];

        $fixedTitle = str_replace($find, $replace, $this->title);

        echo "beginlist \"".$fixedTitle."\"\r\n";

        for($i = 0; $i < count($this->rankings); $i++){

            $r = $this->rankings[$i];

            
            $fixedRank = sprintf("%.2f", $r["rank"]);

            if($r['prevrank'] > $r['rank']){
                $icon = "down";
            }else if($r['prevrank'] < $r['rank']){
                $icon = "up";
            }else{
                $icon = "nc";
            }

            $playerDetails = $this->players[$r['pid']];

            $country = "xx";

            if($playerDetails['country'] !== ""){
                $country = $playerDetails['country'];
            }

            if(isset($playerDetails)){

                $fixedPlayerName = str_replace($find, $replace, $playerDetails['name']);
            
                echo "addplayer \"".$fixedPlayerName."\" ".$fixedRank." ".$country." ".$icon."\r\n";
            }
        }
    }
}


?>

... Please don't laugh too much at my code Feralidragon, i'm very rusty with PHP haven't touched it for ages.


Also I know it's a bit odd developing something against my own utstats stuff :mrgreen:
User avatar
StalkS
Novice
Posts: 10
Joined: Fri May 07, 2021 3:26 pm
Personal rank: =-5t4lk3rZ=-

Re: NexgenStatsViewer105 - depreciated code for 'getstats.php' (php7)

Post by StalkS »

@UT Sniper (SJA94) You sir, conflict of interest or not ,are a legend! Thank you I'll try the new version out later this today.

Edit: Confirmed working! Thank you again @UT Sniper (SJA94)

Just trying to see if I can get it to display the amount of Frags :)
User avatar
UT Sniper (SJA94)
Masterful
Posts: 727
Joined: Thu Jun 24, 2010 10:35 pm
Personal rank: noob programmer
Location: England

Re: NexgenStatsViewer105 - depreciated code for 'getstats.php' (php7)

Post by UT Sniper (SJA94) »

I can add it for you if you would like that.
User avatar
StalkS
Novice
Posts: 10
Joined: Fri May 07, 2021 3:26 pm
Personal rank: =-5t4lk3rZ=-

Re: NexgenStatsViewer105 - depreciated code for 'getstats.php' (php7)

Post by StalkS »

UT Sniper (SJA94) wrote: Mon Jun 07, 2021 10:54 pm I can add it for you if you would like that.
Right...I need to buy you a few beers, or a few coffees..what's your preference? That would be fantastic, thank you!
User avatar
UT Sniper (SJA94)
Masterful
Posts: 727
Joined: Thu Jun 24, 2010 10:35 pm
Personal rank: noob programmer
Location: England

Re: NexgenStatsViewer105 - depreciated code for 'getstats.php' (php7)

Post by UT Sniper (SJA94) »