Leaderboard

Share your ZGE-development tips and techniques here!

Moderator: Moderators

Post Reply
User avatar
Kjell
Posts: 1876
Joined: Sat Feb 23, 2008 11:15 pm

Leaderboard

Post by Kjell »

8)

Something for under the ( digital ) christmas tree. A minimal online leaderboard "interface" using a flat-file database written in PHP5 .. extend to your own needs.

Code: Select all

<?php

define('DATABASE','database.txt');

define('CAPACITY',10);

define('PASSWORD','4e427b8762ace23151f40a1db8d8a47a');
define('SKELETON','4e427b8762ace23151f40a1db8d8a47a');

//

function throwError($type, $message)
{	
	$error .= '<b>';
	
	switch($type)
	{
		case 0:
			$error .= 'Client error';
			break;
		case 1:
			$error .= 'Server error';
			break;
	}
	
	$error .= '</b>: '.$message;
	
	die($error);
}

function checkPassword()
{
	if(!isset($_GET['password']))throwError(0,'Password not found');
	if(hash('md5',$_GET['password']) != PASSWORD)throwError(0,'Password incorrect');
}

function openDatabase($mode)
{
	if(!$handle = @fopen(DATABASE,$mode))throwError(1,'Could not connect to database');
	return $handle;
}

function resetDatabase()
{
	if(!isset($_GET['skeleton']))throwError(0,'Skeleton key not found');	
	if(hash('md5',$_GET['skeleton']) != SKELETON)throwError(0,'Skeleton key incorrect');
		
	$handle = openDatabase('w+');
			
	for($i=0; $i<CAPACITY; ++$i)
	{
		$content[$i] = array(1000-$i*50,'CPU');
	}
		
	fwrite($handle,serialize($content));
	fclose($handle);
}

function getLeaderboard()
{
	$filesize = @filesize(DATABASE);

	if(strval($filesize) == '0')throwError(1,'Database does not contain any data');
	if($filesize == null)throwError(1,'Database could not be located');

	$handle = openDatabase('r');	
	$content = unserialize(@fread($handle,$filesize));
	fclose($handle);
		
	return $content;
}

function echoLeaderboard()
{
	checkPassword();

	$content = getLeaderboard();
	
	for($i=0; $i<CAPACITY; ++$i)
	{
		$output .= '['.$content[$i][1];
		$output .= ']'.$content[$i][0];
	}
	
	echo $output;
}

function submitScore()
{
	checkPassword();

	if(!isset($_GET['score']))throwError(0,'Score not found');
	if(!isset($_GET['name']))throwError(0,'Name not found');
	
	$score = intval($_GET['score']);	
	if(strval($score) != $_GET['score'])throwError(0,'Score is not a integer');
	
	preg_match('/[0-9A-Za-z]+$/',$_GET['name'],$array);
	$name = implode($array);
	if($name != $_GET['name'])throwError(0,'Name contains illegal characters');
	
	$content = getLeaderboard();
	
	$handle = openDatabase('w+');
	
	$content[CAPACITY][0] = $score;
	$content[CAPACITY][1] = $name;
	
	array_multisort($content,SORT_DESC);
	array_pop($content);
	
	@fwrite($handle,serialize($content));
	fclose($handle);
}

//

if(!isset($_GET['command']))throwError(0,'Command not found');

switch($_GET['command'])
{
	case 'get':
		echoLeaderboard();
		break;
	case 'set':
		submitScore();
		break;
	case 'reset':
		resetDatabase();
		break;
	default:
		$error = throwError(0,'Invalid command');
}

?>
Follow the following 7 steps ..

1 - Open leaderboard.php in Notepad.
2 - Set DATABASE to the absolute or relative path* of where you want to store the database file.
3 - Set CAPACITY to the number of entries your leaderboard should hold. Keep this number reasonably low!
4 - Set PASSWORD and SKELETON to your own md5 encrypted passwords.
5 - Adjust the expression on line 52 to your preference ( default scores and names ).
6 - Upload the leaderboard.php file to your server.
7 - Initialize the database using the following command -> leaderboard.php?command=reset&skeleton=secret

* Make sure to CHMOD this folder properly.

From ZGE use the following commands to either get the leaderboard or set a score.

get => leaderboard.php?command=get&password=notsosecret
set => leaderboard.php?command=set&password=notsosecret&name=Kjell&score=1000000

Please report any problems or remarks.

Enjoy ~
K
Attachments
leaderboard.zip
(1.08 KiB) Downloaded 523 times
User avatar
VilleK
Site Admin
Posts: 2274
Joined: Mon Jan 15, 2007 4:50 pm
Location: Stockholm, Sweden
Contact:

Post by VilleK »

Nice work Kjell!

Shouldn't be too hard to use from ZGE, it's only the score to string conversion that requires a little effort.
User avatar
Kjell
Posts: 1876
Joined: Sat Feb 23, 2008 11:15 pm

Post by Kjell »

True,

But hopefully this will only be temporarily until ZGE supports Strings :wink: Until then, use the following function to convert integers.

Code: Select all

int convert(int X)
{
  int C, L;
  
  for(L=0; X>=1; ++L)
  {
    C = X/10*10;    
    String[L] = X-C+48;    
    X /= 10;
  }
  
  return L;
}
* Function returns string length.
* Number is stored in reverse(!), so loop backwards when writing to the score submission ParamArray.

K
User avatar
jph_wacheski
Posts: 1005
Joined: Sat Feb 16, 2008 8:10 pm
Location: Canada
Contact:

Post by jph_wacheski »

This looks good,. thanks for the scripts! I will try it on the SunMurderer game, as that one lends itself to a score board. I have got it working in the browser,. just to test and see if I understand what it is doing,. now just to get the info. sending/receving from within ZGE.

UPDATE- this second converter script fails at high values (>10,000,000) is this just down to rounding errors?? I couldn't get it to work right at first, till I limited it to just 8 characters,. then I notices these rounding errors. I have trouble getting over 500k in my game but I am not the best player ever.., I am considering lowering some of the scoring mechanics to keep it in an acceptable range for this to work.

Also, unless I clear them the Arrays seem to hold there values even when not set to persistant.., is that just in the editor?
Attachments
ascii_string_test.zgeproj
my converter test,. .
(1.14 KiB) Downloaded 630 times
iterationGAMES.com
Post Reply