Advanced Racing With race timer/Script: Difference between revisions

From Armagetron Advanced
Smart (talk | contribs)
No edit summary
Smart (talk | contribs)
No edit summary
Line 1: Line 1:
Last Updated - 8 May 2012
<pre>
<pre>
#!/usr/bin/php
#!/usr/bin/php
Line 5: Line 6:
Includes highscores per map, finish timers, map/cfg rotator, and more
Includes highscores per map, finish timers, map/cfg rotator, and more
Requires a TargetZone as a finish line, winzones will not work
Requires a TargetZone as a finish line, winzones will not work
If you are not using Rx Hosting, make sure your directory has write permissions
If you are not using Rx Hosting your directory needs write permission
Made by dukevin (dukevinjduke@gmail.com)
Made by dukevin (dukevinjduke@gmail.com)
*/
*/


$save_directory_location = "/home/duke/aa/servers/smart/var/logs/";  //The directory to save files. Must end with trailing slash
$save_directory_location = "/home/duke/aa/servers/smart/var/logs/";  //The directory to save files. Must end with trailing slash
$countdown_secs_after_finish = 30; //After someone finishes, how many seconds on the timer before the round ends?
$countdown_secs_after_finish = 30; //After someone finishes, how many seconds on the timer before the round ends?
$countdown_if_last_player = true; //If only 1 player remaining, start the timer?
$countdown_if_last_player = true; //If only 1 player remaining, start the timer?
$countdown_last_player_extra_time = 0; //If only 1 player remaining, give the last racer this many seconds of extra time to finish
 
$max_time_limit = -1; //start the timer after this many seconds, -1 to disable time limits
$max_time_limit = -1; //start the timer after this many seconds, -1 to disable time limits
$points = array(10, 7, 5, 4, 3, 2, 1, 1, 1, 1); //points awarded for 1st, 2nd, 3rd, 4th, 5th, etc...
$points = array(10, 7, 5, 4, 3, 2, 1, 1, 1, 1); //points awarded for 1st, 2nd, 3rd, 4th, 5th, etc...
$display_mode = 1; //If set to "1" display a center_message of the map name, 2 for console_message, 3 for both, 0 for no message
$display_mode = 1; //If set to "1" display a center_message of the map name, 2 for console_message, 3 for both, 0 for no message
$display_prefix = "Current race: 0xffff00"; //When showing the map name, this is appended before it, if $display_mode is 0, this is disabled
$display_prefix = "Current race: 0xffff00"; //When showing the map name, this is appended before it, if $display_mode is 0, this is disabled
$smart_time = true; //If true, the game will determine how many seconds to put on the timer based on previous records instead of using $countdown_secs_after_finish which will be used as the minimum amount of time instead.
$countdown_last_player_extra_time = 0; //If only 1 player remaining, give the last racer this many seconds of extra time to finish. Not needed if $smart_time is true


//Below, inbetween quotes, if you are including maps, put something like: "/path/to/map.aamap.xml". If you are using cfgs, put "mycfg.cfg"  
//Below, inbetween quotes, if you are including maps, put something like: "/path/to/map.aamap.xml". If you are using cfgs, put "mycfg.cfg"  
$includes = array("8Ball.cfg","100Watts.cfg","Aflac.cfg","AnimusonConfusion.cfg","Aoi.cfg","Arsenal.cfg","AtlanticCharter.cfg","Cell.cfg","Cherrio.cfg","Compact.cfg",
$includes = array("Default.cfg","8Ball.cfg","100Watts.cfg","AQuickExplosion.cfg","Aflac.cfg","AnimusonConfusion.cfg","Aoi.cfg","Arsenal.cfg","AtlanticCharter.cfg","Berlin.cfg","Cell.cfg","Cherrio.cfg",
"DevilsSandglass.cfg","Dizzy.cfg","FirePalace.cfg","AQuickExplosion.cfg","BenignRevolution.cfg","BloodyHell.cfg","Chihuahua.cfg","DeathOctagon.cfg","DeathTrap.cfg",
"Compact.cfg","DevilsSandglass.cfg","Dizzy.cfg","FirePalace.cfg","BenignRevolution.cfg","BloodyHell.cfg","Chihuahua.cfg","DeathOctagon.cfg","DeathTrap.cfg","Flex.cfg","FrizzleFraz.cfg","Glacier.cfg",
"Flex.cfg","FrizzleFraz.cfg","Glacier.cfg","Handgrip.cfg","Holiday.cfg","Hyperpod.cfg","Insane.cfg","ItsABug.cfg","JailBreak.cfg","Jelly.cfg","Killzone.cfg","KirbyDance.cfg",
"Handgrip.cfg","Holiday.cfg","Hyperpod.cfg","Illusion.cfg","Insane.cfg","ItsABug.cfg","JailBreak.cfg","Jelly.cfg","Killzone.cfg","KirbyDance.cfg","lol.cfg","Marathon.cfg","Mint.cfg","MissionImpossible.cfg",
"lol.cfg","Marathon.cfg","Mint.cfg","MissionImpossible.cfg","Moon.cfg","MovinOnUp.cfg","MrRoboto.cfg","Mutant.cfg","Nebraska.cfg","Nova.cfg","OctaGone2Death.cfg","PointOfNoReturn.cfg",
"Moon.cfg","MovinOnUp.cfg","MrRoboto.cfg","Mutant.cfg","Nebraska.cfg","Nova.cfg","OctaGone2Death.cfg","PointOfNoReturn.cfg","PureRacingTorture.cfg","RatTunnels.cfg","Red.cfg","Resurrection.cfg",
"PureRacingTorture.cfg","RatTunnels.cfg","Red.cfg","Resurrection.cfg","RoadLessTraveled.cfg","RoadOfDeath.cfg","Roundabout.cfg","Shield.cfg","SidebySide.cfg","SmallSpaces.cfg","Spiral.cfg",
"RoadLessTraveled.cfg","RoadOfDeath.cfg","Roundabout.cfg","Shield.cfg","SidebySide.cfg","SmallSpaces.cfg","Spiral.cfg","SpiralHam.cfg","SquareRoot.cfg","Stardome.cfg","Sun.cfg","Symmetry.cfg",
"SpiralHam.cfg","SquareRoot.cfg","Stardome.cfg","Sun.cfg","Symmetry.cfg","TannersBigTronDaddy.cfg","TheMachine.cfg","TikiTime.cfg","TortureChamber.cfg","Trijecture.cfg","TurnAround.cfg",
"TannersBigTronDaddy.cfg","TheMachine.cfg","TheRoadNotTaken.cfg","TikiTime.cfg","TortureChamber.cfg","Trijecture.cfg","TurnAround.cfg","Unfair.cfg","Unfortunate.cfg","Verta.cfg","Wrapper.cfg","XploderPro.cfg",
"Unfair.cfg","Unfortunate.cfg","Verta.cfg","Wrapper.cfg","XploderPro.cfg","Zero.cfg","ZigZagZaney.cfg","Zipper.cfg","Zone3.cfg");
"Zero.cfg","ZigZagZaney.cfg","Zipper.cfg","Zone3.cfg");
 
$rotate_mode = 2; //Set to 1 for simple random, 2 to play each map in order, 3 to randomly pick a map that hasn't been picked yet.
$rotate_mode = 2; //Set to 1 for simple random, 2 to play each map in order, 3 to randomly pick a map that hasn't been picked yet.
$num_map_plays = 1; //play each map how many times before switching to next map
$num_map_plays = 1; //play each map how many times before switching to next map


$zombie_win = false;  //Does the winner get a zombie? (adjust zombie_zone_speed to fit your liking)
$zombie_win = false;  //Does the winner get a zombie? (adjust zombie_zone_speed to fit your liking)


/*=================================================================*/
$precision = 2; //How many decimal places to show times? A value of 3 shows X.xxx, 2 shows X.xx.  5 is max.
 
/*============================== End of customization options ===================================*/


$reccomended_settings = array("target_initial_score 0", "sp_game_type 0", "game_type 0", "sp_finish_type 0", "finish_type 0", "sp_num_ais 0", "num_ais 0", "shot_seek_update_time 0.1", "ladderlog_write_all 1|1");   
$reccomended_settings = array("target_initial_score 0", "sp_game_type 0", "game_type 0", "sp_finish_type 0", "finish_type 0", "sp_num_ais 0", "num_ais 0", "shot_seek_update_time 0.1",  
//these settings should be set for racing mode and is run once when the script is loaded
"ladderlog_write_all 1|1");  //these settings should be set for racing mode and is run every round
class Player
class Player
{
{
Line 51: Line 65:
function read()
function read()
{
{
global $file;
global $file, $precision;
$lines = file($file);
$lines = file($file);
foreach($lines as $line)
foreach($lines as $line)
{
{
$pieces = explode(" ", $line);  //time name num_plays       (if time is -1, never won it)
$pieces = explode(" ", $line);  //time name num_plays
if($pieces[1] == $this->name)
if($pieces[1] == $this->name)
{
{
$this->best_time = round($pieces[0],2);
$this->best_time = round($pieces[0], $precision);
$this->num_plays = $pieces[2];
$this->num_plays = $pieces[2];
break;
break;
Line 92: Line 106:
file_put_contents($file, $lines);
file_put_contents($file, $lines);
fclose($fp);
fclose($fp);
//return pos
}
}
function finished($time, $place)
function finished($time, $place)
{
{
global $points, $players, $current_inc;
global $points, $players, $current_inc, $precision;
$this->num_plays++;
$this->num_plays++;
$time = round($time,2);
$time = round($time,$precision);
$this->finish_time = $time;
$this->finish_time = $time;
$this->place = $place;
$this->place = $place;
Line 111: Line 124:
{
{
$first = $p->finish_time;
$first = $p->finish_time;
$difference = " 0xffffff(" . round($this->finish_time - $p->finish_time,2) . " s behind 1st)";
$difference = " 0xffffff(" . round($this->finish_time - $p->finish_time,$precision) . " s behind 1st)";
break;
break;
}
}
Line 118: Line 131:
else  
else  
$difference = "";
$difference = "";
c("0xffff00 > 0xffff99$this->pname 0x55ccfffinished $place$sufx in 0xffff99$time 0x55ccffseconds.$difference 0x808080+{$score} pts");
c("0x55ccff > 0xffff99$this->pname 0x55ccfffinished $place$sufx in 0xffff99$time 0x55ccffseconds.$difference 0x808080+{$score} pts");
if($this->finish_time >= $this->best_time && !empty($this->best_time)) //took longer than alltime best
if($this->finish_time >= $this->best_time && !empty($this->best_time)) //took longer than alltime best
{
{
pm($this->name, "    0xaaaaffYour all-time best on 0xddddff{$current_inc}0xaaaaff is 0xffffff{$this->best_time} 0xaaaaffs, you are 0xffffff".($this->finish_time - $this->best_time)." 0xaaaaffs 0xff7777slower0xaaaaff.");
pm($this->name, "    0xaaaaffYour all-time best on 0xddddff{$current_inc}0xaaaaff is 0xffffff{$this->best_time} 0xaaaaffs, you are 0xffffff". round($this->finish_time - $this->best_time, $precision)." 0xaaaaffs 0xff7777slower0xaaaaff.");
}
}
if($this->finish_time < $this->best_time || empty($this->best_time))
if($this->finish_time < $this->best_time || empty($this->best_time))
Line 130: Line 143:
if(empty($this->best_time))  
if(empty($this->best_time))  
pm($this->name, "    0xaaaaffThis is your first time finishing 0xddddff{$current_inc}0xaaaaff!");
pm($this->name, "    0xaaaaffThis is your first time finishing 0xddddff{$current_inc}0xaaaaff!");
else pm($this->name, "  0x3388ff* 0x55ff88New personal record! You improved 0xffffff" . round($this->best_time - $this->finish_time,2) . "0x55ff88 s raising 0xffffff". ($oldrank - $newrank) ." 0x55ff88ranks!");
else pm($this->name, "  0x3388ff* 0x55ff88New personal record! You improved 0xffffff" . round($this->best_time - $this->finish_time,$precision) . "0x55ff88 s raising 0xffffff". ($oldrank - $newrank) ." 0x55ff88ranks!");
if($newrank == 1) c("0xff3333*0xffff33*0x33ff33*0x3366ff*0xffd700Congratulate 0xffffff$this->name 0xffd700for setting a new record on 0xffddaa$current_inc 0xffd700as the fastest time ever!0xff3333*0xffff33*0x33ff33*0x3366ff*");
if($newrank == 1) c("0xff3333*0xffff33*0x33ff33*0x3366ff*0xffd700Congratulate 0xffffff$this->pname 0xffd700for setting a new record on 0xffddaa$current_inc 0xffd700as the fastest time ever!0xff3333*0xffff33*0x33ff33*0x3366ff*");
else if($newrank == 2) c("0xff3333*0xffff33*0x33ff33*0x3366ff*0xffffff$this->name 0xc0c0c0just ranked as the 0xffffff2nd 0xc0c0c0fastest time for $current_inc!0xff3333*0xffff33*0x33ff33*0x3366ff*\n");
else if($newrank == 2) c("0xff3333*0xffff33*0x33ff33*0x3366ff*0xffffff$this->pname 0xc0c0c0just ranked 0xffffff2nd 0xc0c0c0as the fastest time for $current_inc!0xff3333*0xffff33*0x33ff33*0x3366ff*\n");
else if($newrank == 3) c("0xff3333*0xffff33*0x33ff33*0x3366ff*0xffffff$this->name 0xcd7f32just ranked as the 0xffcc003rd 0xcd7f32 fastest time for $current_inc!0xff3333*0xffff33*0x33ff33*0x3366ff*");
else if($newrank == 3) c("0xff3333*0xffff33*0x33ff33*0x3366ff*0xffffff$this->name 0xcd7f32just ranked 0xffcc003rd 0xcd7f32as the fastest time for $current_inc!0xff3333*0xffff33*0x33ff33*0x3366ff*");
else
else
pm($this->name, "   0xaaaaaaYou are now rank 0xffffff$newrank 0xaaaaaaon the list of fastest times for 0xcccccc{$current_inc}0xaaaaaa!");
pm($this->name, "     0xaaaaaaYou are now rank 0xffffff$newrank 0xaaaaaaon the list of fastest times for 0xcccccc{$current_inc}0xaaaaaa!");
}
}
echo "add_score_player $this->name " . $score . " \n";
echo "add_score_player $this->name " . $score . "\n";
}
}
}
}
Line 152: Line 164:
$split = explode(" ",$line);
$split = explode(" ",$line);
$name = $split[1];
$name = $split[1];
if(getObject($name) !== false)
{
$num_racers++;
goto end;
}
if(strstr($name,"\""))
if(strstr($name,"\""))
{
{
Line 179: Line 196:
if(!empty($players[$i]->best_time)) $rank = filetee($players[$i]->name, $players[$i]->name, 1, false, true) + 1;
if(!empty($players[$i]->best_time)) $rank = filetee($players[$i]->name, $players[$i]->name, 1, false, true) + 1;
$sufx = suffix($rank);
$sufx = suffix($rank);
pm($players[$i]->name, "0x808080Top 3 times for $current_inc:");
filetee($players[$i]->name, $players[$i]->name, 3, true);
if(!(strstr($players[$i]->name, '@')))
if(!(strstr($players[$i]->name, '@')))
$remind = "0x808080(Maybe because you're logged out?)";
$remind = "0x808080(Maybe because you're logged out?)";
else
else
$remind = null;
$remind = null;
if(!empty($players[$i]->best_time)) pm($players[$i]->name, "0xaaddaaYour best time for $current_inc is 0xffffff{$players[$i]->best_time}0xaaddaa s ranking 0xffffff$rank{$sufx}0xaaddaa.");
if(!empty($players[$i]->best_time)) pm($players[$i]->name, "0x99ddffYour best time for $current_inc is 0xffffff{$players[$i]->best_time}0x99ddff s ranking 0xffffff$rank{$sufx}0x99ddff. 0x808080{$players[$i]->num_plays} finishes");
if(empty($players[$i]->best_time)) pm($players[$i]->name, "0xaaddaaYou have never won 0xcccccc$current_inc 0xaaddaabefore. $remind");
if(empty($players[$i]->best_time)) pm($players[$i]->name, "0x99ddffYou have never won 0xcccccc$current_inc 0x99ddffbefore. $remind");
pm($players[$i]->name, "0x808080Top 3 times for $current_inc:");
filetee($players[$i]->name, $players[$i]->name, 3, true);
if(!(strstr($players[$i]->name, '@')))
pm($players[$i]->name, "0xffddaaYou should /login to protect your times!");
$i++;
$i++;
Line 208: Line 223:
foreach($reccomended_settings as $s)
foreach($reccomended_settings as $s)
echo "$s \n";
echo "$s \n";
echo "target_survive_time " . ($countdown_secs_after_finish+1) ."\n";
unset($players);
unset($players);
$finished = 0;
$finished = 0;
Line 235: Line 249:
c("0xffff77Warning: 0xffffff$current_inc.txt not found, creating it...");
c("0xffff77Warning: 0xffffff$current_inc.txt not found, creating it...");
fopen($file, 'w');
fopen($file, 'w');
sleep(1);
if(!file_exists($file))
c("0xff7777Warning: 0xffffffFile creation failed, scores cannot be saved! Does your directory have write permission?");
}
}
if(mt_rand(0,7)==7) c("0x808080You can type /stats <name> <amount> to view high scores for maps.");
if($smart_time)
$countdown_secs_after_finish = smart_time($countdown_secs_after_finish);
echo "target_survive_time " . ($countdown_secs_after_finish+1) ."\n";
if(mt_rand(0,7)==7) c("0x808080You can type /stats <name> <optional amount> to view high scores for maps.");
@clock("stop");
@clock("stop");
}
}
Line 252: Line 273:
}
}
sleep(1);
sleep(1);
echo "center_message Winner: $split[6]\n";
if(!empty($split[6])) echo "center_message Winner: {$split[6]}\n";
echo "collapse_zone\n";
echo "collapse_zone\n";
if(empty($split[6]))
echo "spawn_zone win $xPos $yPos 1000000 10000 0 0 false 0 0 0\n";
$a_player_finished = true;
$a_player_finished = true;
}
}
Line 260: Line 283:
$split = explode(" ", $line);
$split = explode(" ", $line);
//INVALID_COMMAND /cast rx"dukevin 76.174.69.46 accesslevel argument 50
//INVALID_COMMAND /cast rx"dukevin 76.174.69.46 accesslevel argument 50
if($split[1] == "/stats" || $split[1] == "/s")
if($split[1] == "/stats" || $split[1] == "/s"|| $split[1] == "/search")
{
{
if($split[6] < 0) $split[6] = 0;
if(empty($split[5]))
if(empty($split[5]))
{
{
Line 268: Line 290:
goto end;
goto end;
}
}
filetee($split[5], $split[2], $split[6]);
$obj = getObject($split[2]);
if(empty($split[6]) || !isset($split[6])) $split[6] = 3;
search($obj, $split[5], $split[6]);
}
}
elseif($split[1] == "/version" || $split[1] == "/v" || $split[1] == "/ver" || $split[1] == "/vers")
elseif($split[1] == "/version" || $split[1] == "/v" || $split[1] == "/ver" || $split[1] == "/vers")
Line 274: Line 298:
$obj = getObject($split[2]);
$obj = getObject($split[2]);
version($obj);
version($obj);
}
elseif($split[1] == "/debug")
{
foreach($players as $p)
pm($split[2], "$p->name");
}
}
else
else
Line 320: Line 349:
{
{
$split = explode(" ", $line);
$split = explode(" ", $line);
if(empty(getObject($split[1])->place))
if(empty(getObject($split[1])->finish_time))
$num_racers--;
$num_racers--;
if(sizeof($players) <= 1) //if only 1 player, don't start the timer
if(sizeof($players) <= 1) //if only 1 player, don't start the timer
Line 328: Line 357:
if($num_racers <= 1)
if($num_racers <= 1)
{
{
if(@clock("getState") == "active")
if(@clock("getState") == "active" && (empty(getObject($split[1])->finish_time))) //only winner alive, last racer died &&racer not finish
{
{
echo "spawn_zone win $xPos $yPos 1000000 100000 0 0 false 0 0 0\n";
echo "spawn_zone win $xPos $yPos 1000000 100000 0 0 false 0 0 0\n";
foreach($players as $p)
filetee($p->name, $p->name, 3);
@clock("stop");
@clock("stop");
goto end;
goto end;
Line 371: Line 402:
echo "admin_kill_message 0\n";
echo "admin_kill_message 0\n";
foreach($players as $p)
foreach($players as $p)
{
echo "kill $p->name \n";
echo "kill $p->name \n";
}
echo "admin_kill_message 1\n";
echo "admin_kill_message 1\n";
}
}
sleep(1);
foreach($players as $p)
filetee($p->name, $p->name, 3);
$state = "stopped";
$state = "stopped";
return;
return;
Line 387: Line 419:
function filetee($search, $requester, $amount = 3, $display_top = false, $onlyrank = false)
function filetee($search, $requester, $amount = 3, $display_top = false, $onlyrank = false)
{
{
global $file, $current_inc;
global $file;
$found = false;
$found = false;
$lines = file($file);
$lines = file($file);
Line 402: Line 434:
}
}
if($display_top) $i = 0;
if($display_top) $i = 0;
if($amount > 150) $amount = 150;
if($amount %2 == 0) $amount += 1;
if($amount %2 == 0) $amount += 1;
$amount = floor($amount/2);
$amount = floor($amount/2);
if($i == 0 || $i == sizeof($lines)-1) //display an extra entry for 1st and last place
if($i == 0 || $i == sizeof($lines)-1) //display an extra entry for 1st and last place
$amount += 1;
$amount += 1;
if($found == false && !$display_top && !$onlyrank) pm($requester, "0xff7777$search not found on the list of fastest times for $current_inc");
if($found == false && $display_top == false)
return false;
for($x = $i-$amount; $x <= $i+$amount; $x++)
for($x = $i-$amount; $x <= $i+$amount; $x++)
{
{
Line 416: Line 450:
function suffix($number)
function suffix($number)
{
{
if($number == 1) $sufx = "st";
$n = (string)$number;
elseif($number == 2) $sufx = "nd";
    $n = $n[strlen($n)-1];
elseif($number == 3) $sufx = "rd";
if($n == 1) $sufx = "st";
elseif($n == 2) $sufx = "nd";
elseif($n == 3) $sufx = "rd";
else $sufx = "th";
else $sufx = "th";
if($number == 11 || $number == 12 || $number == 13) //english is weird
$sufx = "th";
return $sufx;
return $sufx;
}
}
Line 430: Line 468:
$tail = $mapname;
$tail = $mapname;
echo $head . " " . $tail . "\n";
echo $head . " " . $tail . "\n";
foreach($players as $p)
$p->finish_time = -1;
$cut = explode("/", $tail);
$cut = explode("/", $tail);
Line 442: Line 478:
}
}
$cut = explode("-", $current_inc);
$cut = explode("-", $current_inc);
$current_inc = $cut[0];
$current_inc = trim($cut[0]);
$current_inc = trim($current_inc);
if(empty($current_inc)) c("0xff7777Warning: 0xffffffUnable to retrieve current map name.");
return empty($current_inc) ? "null" : $current_inc;
return empty($current_inc) ? "null" : $current_inc;
}
}
Line 474: Line 510:
function pickmap($includes, $rotate_mode)
function pickmap($includes, $rotate_mode)
{
{
static $i, $played;
static $i;
if($rotate_mode == 1)
if($rotate_mode == 1)
return $includes[mt_rand(0, sizeof($includes)-1)];
return $includes[mt_rand(0, sizeof($includes)-1)];
Line 493: Line 529:
}
}
}
}
function smart_time($countdown_secs_after_finish)
{
global $file, $current_inc;
static $initial_countdown_secs;
if(empty($initial_countdown_secs)) $initial_countdown_secs = $countdown_secs_after_finish;
if($initial_countdown_secs < 100)
$MAX_TIME = 75; //smart time will not allow more than 75 secs
else
$MAX_TIME = $initial_countdown_secs * 1.3;
$lines = file($file);
if(!file_exists($file)) return $initial_countdown_secs;
$split = explode(" ", $lines[0]);
$hs = $split[0];
$split = explode(" ", $lines[1]);
$hs2nd = $split[0];
if(empty($hs)) return 60;
if($hs*1.3 < $initial_countdown_secs) return $initial_countdown_secs;
if(empty($hs2nd)) return ($hs*2) > $MAX_TIME ? $MAX_TIME : round($hs*2);
if(($hs2nd - $hs) > 8) $hs = $hs2nd;
return ($hs*1.3) > $MAX_TIME ? $MAX_TIME : round($hs*1.3);
}
function search($me, $search, $amount = 3)
{
global $players;
$count = 0;
foreach($players as $p)
{
if($p->pname == $search || $p->name == $search)
{
$found = $p->name;
$count = 1;
break;
}
if(stripos("{$p->pname}","$search") !== false || stripos("{$p->name}","$search") !== false)
{
$count++;
$found = $p->name;
}
}
if($count > 1)
pm($me->name, "More than one player with the name '$search', using $found.");
if(empty($count))
{
if(filetee($search, $me->name, $amount, false, false) == false)
{
global $file;
$lines = file($file);
foreach($lines as $line)
{
$pieces = explode(" ", $line);
if(stripos("$pieces[1]","$search") !== false)
{
$found = $pieces[1];
$count++;
break;
}
}
}
}
if(empty($found) || empty($count) || filetee($found, $me->name, -2, false, false) === false)
{
pm($me->name, "No times found for player: $search");
return;
}
filetee($found, $me->name, $amount, false, false);
}
function version($me)
function version($me)
{
{
Line 499: Line 603:
pm($me->name, "0xffff00Made for smart's server");
pm($me->name, "0xffff00Made for smart's server");
}
}
/*
known bugs:
-respawn breaks script
-you should login to protect your times not showing
-times showed twise if time run out
-if you never won, top 3 won't show
foreach($players as $p)
{
if(!(strstr($p->name, '@')))
pm($p->name, "0xffddaaYou should /login to protect your times!");
}
*/
?>
?>
</pre>
</pre>

Revision as of 05:54, 8 May 2012

Last Updated - 8 May 2012

#!/usr/bin/php
<?php
/*  Race Script
		Includes highscores per map, finish timers, map/cfg rotator, and more
		Requires a TargetZone as a finish line, winzones will not work
		If you are not using Rx Hosting your directory needs write permission
		Made by dukevin (dukevinjduke@gmail.com)
*/

$save_directory_location = "/home/duke/aa/servers/smart/var/logs/";   //The directory to save files. Must end with trailing slash

$countdown_secs_after_finish = 30;	//After someone finishes, how many seconds on the timer before the round ends?

$countdown_if_last_player = true; //If only 1 player remaining, start the timer?

$max_time_limit = -1; //start the timer after this many seconds, -1 to disable time limits

$points = array(10, 7, 5, 4, 3, 2, 1, 1, 1, 1); //points awarded for 1st, 2nd, 3rd, 4th, 5th, etc...

$display_mode = 1; //If set to "1" display a center_message of the map name, 2 for console_message, 3 for both, 0 for no message

$display_prefix = "Current race: 0xffff00"; //When showing the map name, this is appended before it, if $display_mode is 0, this is disabled

$smart_time = true; //If true, the game will determine how many seconds to put on the timer based on previous records instead of using $countdown_secs_after_finish which will be used as the minimum amount of time instead.

$countdown_last_player_extra_time = 0; //If only 1 player remaining, give the last racer this many seconds of extra time to finish. Not needed if $smart_time is true

//Below, inbetween quotes, if you are including maps, put something like: "/path/to/map.aamap.xml". If you are using cfgs, put "mycfg.cfg" 
$includes = array("Default.cfg","8Ball.cfg","100Watts.cfg","AQuickExplosion.cfg","Aflac.cfg","AnimusonConfusion.cfg","Aoi.cfg","Arsenal.cfg","AtlanticCharter.cfg","Berlin.cfg","Cell.cfg","Cherrio.cfg",
"Compact.cfg","DevilsSandglass.cfg","Dizzy.cfg","FirePalace.cfg","BenignRevolution.cfg","BloodyHell.cfg","Chihuahua.cfg","DeathOctagon.cfg","DeathTrap.cfg","Flex.cfg","FrizzleFraz.cfg","Glacier.cfg",
"Handgrip.cfg","Holiday.cfg","Hyperpod.cfg","Illusion.cfg","Insane.cfg","ItsABug.cfg","JailBreak.cfg","Jelly.cfg","Killzone.cfg","KirbyDance.cfg","lol.cfg","Marathon.cfg","Mint.cfg","MissionImpossible.cfg",
"Moon.cfg","MovinOnUp.cfg","MrRoboto.cfg","Mutant.cfg","Nebraska.cfg","Nova.cfg","OctaGone2Death.cfg","PointOfNoReturn.cfg","PureRacingTorture.cfg","RatTunnels.cfg","Red.cfg","Resurrection.cfg",
"RoadLessTraveled.cfg","RoadOfDeath.cfg","Roundabout.cfg","Shield.cfg","SidebySide.cfg","SmallSpaces.cfg","Spiral.cfg","SpiralHam.cfg","SquareRoot.cfg","Stardome.cfg","Sun.cfg","Symmetry.cfg",
"TannersBigTronDaddy.cfg","TheMachine.cfg","TheRoadNotTaken.cfg","TikiTime.cfg","TortureChamber.cfg","Trijecture.cfg","TurnAround.cfg","Unfair.cfg","Unfortunate.cfg","Verta.cfg","Wrapper.cfg","XploderPro.cfg",
"Zero.cfg","ZigZagZaney.cfg","Zipper.cfg","Zone3.cfg");

$rotate_mode = 2; //Set to 1 for simple random, 2 to play each map in order, 3 to randomly pick a map that hasn't been picked yet.

$num_map_plays = 1; //play each map how many times before switching to next map

$zombie_win = false;  //Does the winner get a zombie? (adjust zombie_zone_speed to fit your liking)

$precision = 2; //How many decimal places to show times? A value of 3 shows X.xxx, 2 shows X.xx.  5 is max. 

/*============================== End of customization options ===================================*/

$reccomended_settings = array("target_initial_score 0", "sp_game_type 0", "game_type 0", "sp_finish_type 0", "finish_type 0", "sp_num_ais 0", "num_ais 0", "shot_seek_update_time 0.1", 
"ladderlog_write_all 1|1");  //these settings should be set for racing mode and is run every round
class Player
{
	var $name;
	var $pname;
	var $place;
	var $finish_time;
	var $best_time;
	var $num_plays;
	function __construct($name) 
	{
		$this->name = $name;
		$this->read();
		if(empty($this->num_plays)) $this->num_plays = 0;
	}
	function read()
	{
		global $file, $precision;
		$lines = file($file);
		foreach($lines as $line)
		{
			$pieces = explode(" ", $line);  //time name num_plays
			if($pieces[1] == $this->name)
			{
				$this->best_time = round($pieces[0], $precision);
				$this->num_plays = $pieces[2];
				break;
			}
		}
	}
	function write()
	{
		global $file, $current_inc;
		$found = false;
		$lines = file($file);
		if(!file_exists($file))
		{
			c("0xff7777Warning: 0xffffffFile '$current_inc.txt' not found, file creation may have failed. Retrying...");
			$fp = fopen($file, 'w');
		}
		foreach($lines as $i => $line)
		{
			$pieces = explode(" ", $line);
			$pieces[1] = trim($pieces[1]);
			if($pieces[1] == $this->name)
			{
				$lines[$i] = "$this->finish_time $this->name $this->num_plays \n";
				$found = true;
				break;
			}
		}
		if(!$found)
		{
			$lines[] = "$this->finish_time $this->name $this->num_plays \n";
		}
		sort(&$lines, SORT_NUMERIC);
		file_put_contents($file, $lines);
		fclose($fp);
	}
	function finished($time, $place)
	{
		global $points, $players, $current_inc, $precision;
		$this->num_plays++;
		$time = round($time,$precision);
		$this->finish_time = $time;
		$this->place = $place;
		$sufx = suffix($place);
		$score = $points[$place-1];
		if(empty($score)) $score = 0;
		if($place > 1)
		{
			foreach($players as $p)
			{
				if($p->place == 1)
				{
					$first = $p->finish_time;
					$difference = " 0xffffff(" . round($this->finish_time - $p->finish_time,$precision) . " s behind 1st)";
					break;
				}
			}
		}
		else 
			$difference = "";
		c("0x55ccff > 0xffff99$this->pname 0x55ccfffinished $place$sufx in 0xffff99$time 0x55ccffseconds.$difference 0x808080+{$score} pts");
		if($this->finish_time >= $this->best_time && !empty($this->best_time)) //took longer than alltime best
		{
			pm($this->name, "    0xaaaaffYour all-time best on 0xddddff{$current_inc}0xaaaaff is 0xffffff{$this->best_time} 0xaaaaffs, you are 0xffffff". round($this->finish_time - $this->best_time, $precision)." 0xaaaaffs 0xff7777slower0xaaaaff.");
		}
		if($this->finish_time < $this->best_time || empty($this->best_time))
		{
			if(!empty($this->best_time)) $oldrank = filetee($this->name, $this->name, 1, false, true) + 1;
			$this->write();
			$newrank = filetee($this->name, $this->name, 1, false, true) + 1;
			if(empty($this->best_time)) 
				pm($this->name, "    0xaaaaffThis is your first time finishing 0xddddff{$current_inc}0xaaaaff!");
			else pm($this->name, "  0x3388ff* 0x55ff88New personal record! You improved 0xffffff" . round($this->best_time - $this->finish_time,$precision) . "0x55ff88 s raising 0xffffff". ($oldrank - $newrank) ." 0x55ff88ranks!");
			if($newrank == 1) c("0xff3333*0xffff33*0x33ff33*0x3366ff*0xffd700Congratulate 0xffffff$this->name 0xffd700for setting a new record on 0xffddaa$current_inc 0xffd700as the fastest time ever!0xff3333*0xffff33*0x33ff33*0x3366ff*");
			else if($newrank == 2) c("0xff3333*0xffff33*0x33ff33*0x3366ff*0xffffff$this->name 0xc0c0c0just ranked as the 0xffffff2nd 0xc0c0c0fastest time for $current_inc!0xff3333*0xffff33*0x33ff33*0x3366ff*\n");
			else if($newrank == 3) c("0xff3333*0xffff33*0x33ff33*0x3366ff*0xffffff$this->name 0xcd7f32just ranked as the 0xffcc003rd 0xcd7f32 fastest time for $current_inc!0xff3333*0xffff33*0x33ff33*0x3366ff*");
			else
				pm($this->name, "     0xaaaaaaYou are now rank 0xffffff$newrank 0xaaaaaaon the list of fastest times for 0xcccccc{$current_inc}0xaaaaaa!");
			
		}
		echo "add_score_player $this->name " . $score . "\n";
	}
}
$players = array();
$finished = 0;

while(true)
{
	$line = rtrim(fgets(STDIN, 1024));
	if(preg_match("/^CYCLE_CREATED/", $line))
	{
		$split = explode(" ",$line);
		$name = $split[1];
		if(getObject($name) !== false)
		{
			$num_racers++;
			goto end;
		}
		if(strstr($name,"\""))
		{	
			c("0x000000 ! 0xffff00 $name is not allowed to use the characters 0xffffff« or \" 0xffff00 in their name.");
			$clean = str_replace("\"","_",$name);
			$wo = str_replace("\"","",$name);
			echo "rename $wo $clean \n";
			echo "rename $name $clean \n";
		}
		$players[$i] = new Player($split[1]);
		if(isset($pretty))
		{
			for($x = 0; $x < sizeof($pretty); $x++)
			{
				$crack = explode("*%$", $pretty[$x]);
				if($crack[0] == $players[$i]->name)
					$players[$i]->pname = trim($crack[1]);
			}
		}
		if(!isset($players[$i]->pname))
			$players[$i]->pname = $players[$i]->name;
		if($i == 0)
		{
			$xPos = $split[2];
			$yPos = $split[3];
		}
		if(!empty($players[$i]->best_time)) $rank = filetee($players[$i]->name, $players[$i]->name, 1, false, true) + 1;
		$sufx = suffix($rank);
		pm($players[$i]->name, "0x808080Top 3 times for $current_inc:");
		filetee($players[$i]->name, $players[$i]->name, 3, true);
		if(!(strstr($players[$i]->name, '@')))
			$remind = "0x808080(Maybe because you're logged out?)";
		else
			$remind = null;
		if(!empty($players[$i]->best_time)) pm($players[$i]->name, "0x99ddffYour best time for $current_inc is 0xffffff{$players[$i]->best_time}0x99ddff s ranking 0xffffff$rank{$sufx}0x99ddff. 0x808080{$players[$i]->num_plays} finishes");
		if(empty($players[$i]->best_time)) pm($players[$i]->name, "0x99ddffYou have never won 0xcccccc$current_inc 0x99ddffbefore. $remind");
	
		$i++;
		$num_racers = $i;
	}
	if(preg_match("/^PLAYER_ENTERED/", $line))
	{   
		//PLAYER_ENTERED rx"dukevin 76.174.69.46 Rx«dukevin
		$split = explode(" ", $line);
		$pretty[] = $split[1] . "*%$" . $split[3] . " " . $split[4] . " " . $split[5];
	}
	if(preg_match("/^PLAYER_RENAMED/", $line))
	{
		$split = explode(" ", $line);
		$pretty[] = $split[2] . "*%$" . $split[5] . " " . $split[6] . " " . $split[7];
	}
	if(preg_match("/^ROUND_COMMENCING/", $line))
	{
		foreach($reccomended_settings as $s)
			echo "$s \n";
		unset($players);
		$finished = 0;
		$num_racers = 0;
		$a_player_finished = false;
		$i = 0;
		if(empty($num_plays)) $num_plays = 0;
		$num_plays++;
		if($num_plays >= $num_map_plays)
		{
			$pick = pickmap($includes, $rotate_mode);
			$num_plays = 0;
		}
		$current_inc = retrieve($pick);
		c("Reading $current_inc.txt...");
		if($display_mode == 1) echo "center_message $display_prefix$current_inc\n";
		if($display_mode == 2) c("$display_prefix$current_inc");
		if($display_mode == 3) 
		{
			echo "center_message $display_prefix$current_inc\n";
			c("$display_prefix$current_inc");
		}
		$file = "$save_directory_location" . "$current_inc" . ".txt";
		if(!file_exists($file))
		{
			c("0xffff77Warning: 0xffffff$current_inc.txt not found, creating it...");
			fopen($file, 'w');
			sleep(1);
			if(!file_exists($file))
				c("0xff7777Warning: 0xffffffFile creation failed, scores cannot be saved! Does your directory have write permission?");
		}
		if($smart_time)
			$countdown_secs_after_finish = smart_time($countdown_secs_after_finish);
		echo "target_survive_time " . ($countdown_secs_after_finish+1) ."\n";
		if(mt_rand(0,7)==7) c("0x808080You can type /stats <name> <optional amount> to view high scores for maps.");
		
		@clock("stop");
	}
	if(preg_match("/^TARGETZONE_CONQUERED/", $line) || preg_match("/^ROUND_SCORE/",$line))
	{
		if($finished == 0 || $a_player_finished == true)
			goto end;
		@clock("stop");
		$split = explode(" ", $line);
		if(preg_match("/^TARGETZONE_CONQUERED/", $line))
		{
			echo "spawn_zone win $split[3] $split[4] 1000000 10000 0 0 false 0 0 0\n";
			foreach($players as $p)
				filetee($p->name, $p->name, 3);
		}
		sleep(1);
		if(!empty($split[6])) echo "center_message Winner: {$split[6]}\n";
		echo "collapse_zone\n";
		if(empty($split[6]))
			echo "spawn_zone win $xPos $yPos 1000000 10000 0 0 false 0 0 0\n";
		$a_player_finished = true;
	}
	if(preg_match("/^INVALID_COMMAND/", $line))
	{
		$split = explode(" ", $line);
		//INVALID_COMMAND /cast rx"dukevin 76.174.69.46 accesslevel argument 50
		if($split[1] == "/stats" || $split[1] == "/s"|| $split[1] == "/search")
		{
			if(empty($split[5]))
			{
				pm($split[2], "0xff7777Invalid usage, try 0xffffff/stats <name> <amount>");
				goto end;
			}
			$obj = getObject($split[2]);
			if(empty($split[6]) || !isset($split[6])) $split[6] = 3;
			search($obj, $split[5], $split[6]);
		}
		elseif($split[1] == "/version" || $split[1] == "/v" || $split[1] == "/ver" || $split[1] == "/vers")
		{
			$obj = getObject($split[2]);
			version($obj);
		}
		elseif($split[1] == "/debug")
		{
			foreach($players as $p)
				pm($split[2], "$p->name");
		}
		else
		{
			pm($split[2], "0xff7777Invalid command, try 0xffffff/stats <name> <amount>");
		}
	}
	if(preg_match("/^TARGETZONE_PLAYER_ENTER/", $line))
	{
		//TARGETZONE_PLAYER_ENTER 2 zonename 100 100 dukevin 90.8824 103.506 1 0 37.6366
		$split = explode(" ", $line);
		$name = $split[5];
		$time = $split[10];
		$obj = getObject($name);
		if(!method_exists($obj,'finished'))
		{	
			c("0xffff77Warning: 0xffffffNo object to operate on, perhaps you just loaded scripts?");
			echo "admin_kill_message 0\n";
			echo "kill $name\n";
			echo "admin_kill_message 1\n";
			goto end;
		}
		if($obj->finish_time > 0) //already hit the finish line
			goto end;
		$finished++;
		$obj->finished($time, $finished);
		$num_racers--;
		if($zombie_win) zombieplz($split[5], $split[6], $split[7]);
		@clock("start", $countdown_secs_after_finish);
		if($num_racers <= 0)
			echo "target_survive_time " . 1 ."\n";
	}
	if(preg_match("/^GAME_TIME/", $line))
	{
		@clock("tick");
		if($max_time_limit <= 0)
			goto end;
		else
		{
			$split = explode(" ", $line);
			if($split[1] == $max_time_limit)
				clock("start", $countdown_secs_after_finish, "kill");
		}
	}
	if(preg_match("/^DEATH_FRAG|DEATH_SUICIDE|PLAYER_KILLED|DEATH_SHOT_FRAG|DEATH_DEATHZONE|DEATH_SHOT_SUICIDE|DEATH_TEAMKILL|DEATH_SHOT_TEAMKILL|DEATH_ZOMBIEZONE|DEATH_DEATHSHOT|DEATH_SELF_DESTRUCT/", $line))
	{
		$split = explode(" ", $line);
		if(empty(getObject($split[1])->finish_time))
			$num_racers--;
		if(sizeof($players) <= 1) //if only 1 player, don't start the timer
			goto end;
		if($countdown_if_last_player == false) //don't start the timer if user doesn't want it
			goto end;
		if($num_racers <= 1)
		{
			if(@clock("getState") == "active" && (empty(getObject($split[1])->finish_time))) //only winner alive, last racer died &&racer not finish
			{
				echo "spawn_zone win $xPos $yPos 1000000 100000 0 0 false 0 0 0\n";
				foreach($players as $p)
					filetee($p->name, $p->name, 3);
				@clock("stop");
				goto end;
			}
			if($num_racers != 0) clock("start", $countdown_secs_after_finish + $countdown_last_player_extra_time, "kill");
		}
	}
	
end:
}

function clock($action, $duration, $options)
{
	static $state, $time, $options;
	if($action == "start")
	{
		if($state == "active")
			return;
		$state = "active";
		$time = $duration;
		echo("center_message 0xff7777$time               \n");
	}
	if($action == "stop" || $state == "stopped")
	{
		$state = "stopped";
		$options = null;
		return;
	}
	if($action == "tick")
	{
		if($state == "stopped")
			return;
		$time--;
		echo("center_message 0xff7777$time               \n");
		if(empty($time) || $time < 0)
		{
			if($options = "kill")
			{
				global $players;
				echo "admin_kill_message 0\n";
				foreach($players as $p)
					echo "kill $p->name \n";
				echo "admin_kill_message 1\n";
			}
			sleep(1);
			foreach($players as $p)
				filetee($p->name, $p->name, 3);
			$state = "stopped";
			return;
		}
	}
	if($action == "getState")
	{
		return $state;
	}
}
function filetee($search, $requester, $amount = 3, $display_top = false, $onlyrank = false)
{
	global $file;
	$found = false;
	$lines = file($file);
	foreach($lines as $i => $line)
	{
		$pieces = explode(" ", $line);
		$pieces[1] = trim($pieces[1]);
		if($pieces[1] == $search) 
		{	
			$found = true;
			if($onlyrank) return $i;
			break;
		}
	}
	if($display_top) $i = 0;
	if($amount > 150) $amount = 150;
	if($amount %2 == 0) $amount += 1;
	$amount = floor($amount/2);
	if($i == 0 || $i == sizeof($lines)-1) //display an extra entry for 1st and last place
		$amount += 1;
	if($found == false && $display_top == false)
		return false;
	for($x = $i-$amount; $x <= $i+$amount; $x++)
	{
		$cut = explode(" ", $lines[$x]);
		$color = ($cut[1] == $search) ? '0xffff88' : '0xcccccc';
		if(!empty($cut[0])) pm($requester, $color . ($x+1) . ") $cut[0] - $cut[1]");
	}
}
function suffix($number)
{
	$n = (string)$number;
    $n = $n[strlen($n)-1];
	if($n == 1) $sufx = "st";
	elseif($n == 2) $sufx = "nd";
	elseif($n == 3) $sufx = "rd";
	else $sufx = "th";
	if($number == 11 || $number == 12 || $number == 13) //english is weird
		$sufx = "th";
	return $sufx;
}
function retrieve($mapname)
{
	$type = explode(".", $mapname);
	if($type[sizeof($type)-1] == "xml") $head = "MAP_FILE";
	elseif($type[sizeof($type)-1] == "cfg") $head = "INCLUDE";
	
	$tail = $mapname;
	echo $head . " " . $tail . "\n";
	
	$cut = explode("/", $tail);
	$split = explode(".", $cut[sizeof($cut)-1]);
	foreach($split as $element)
	{
		if($element == "aamap" || $element == "xml" || $element == "cfg")
			unset($element);
		$current_inc .= $element;
	}
	$cut = explode("-", $current_inc);
	$current_inc = trim($cut[0]);
	if(empty($current_inc)) c("0xff7777Warning: 0xffffffUnable to retrieve current map name.");
	return empty($current_inc) ? "null" : $current_inc;
}

function zombieplz($name, $x, $y)
{
	echo "spawn_zone zombieOwner $name $name $x $y 1 0 0 0 false\n";
}
function c($string){
	echo "console_message $string \n";
}
function pm($name, $string){
	echo "player_message {$name} \"{$string}\"\n";
}
function getObject($name)
{
	global $players;
	foreach($players as $p)
	{
		if($p->name == $name)
		return $p;
	}
	foreach($players as $p)
	{
		if($p->pname == $name)
		return $p;
	}
	return false;
}
function pickmap($includes, $rotate_mode)
{
	static $i;
	if($rotate_mode == 1)
		return $includes[mt_rand(0, sizeof($includes)-1)];
	if($rotate_mode == 2)
	{
		if($i > sizeof($includes)-1 || empty($i)) $i = 0;
		$x = $i;
		$i++;
		return $includes[$x];
	}
	if($rotate_mode == 3)
	{
		if($i > sizeof($includes)-1 || empty($i)) $i = 0;
		if($i == 0) shuffle($includes);
		$x = $i;
		$i++;
		return $includes[$x];
	}
}
function smart_time($countdown_secs_after_finish)
{
	global $file, $current_inc;
	static $initial_countdown_secs;
	if(empty($initial_countdown_secs)) $initial_countdown_secs = $countdown_secs_after_finish;
	if($initial_countdown_secs < 100)
		$MAX_TIME = 75; //smart time will not allow more than 75 secs
	else
		$MAX_TIME = $initial_countdown_secs * 1.3;
	$lines = file($file);
	if(!file_exists($file))	return $initial_countdown_secs;
	$split = explode(" ", $lines[0]);
	$hs = $split[0];
	$split = explode(" ", $lines[1]);
	$hs2nd = $split[0];
	if(empty($hs)) return 60;
	
	if($hs*1.3 < $initial_countdown_secs) return $initial_countdown_secs;
	if(empty($hs2nd)) return ($hs*2) > $MAX_TIME ? $MAX_TIME : round($hs*2);
	if(($hs2nd - $hs) > 8) $hs = $hs2nd;
	return ($hs*1.3) > $MAX_TIME ? $MAX_TIME : round($hs*1.3);
}
function search($me, $search, $amount = 3)
{
	global $players;
	$count = 0;
	foreach($players as $p)
	{
		if($p->pname == $search || $p->name == $search)
		{
			$found = $p->name;
			$count = 1;
			break;
		}
		if(stripos("{$p->pname}","$search") !== false || stripos("{$p->name}","$search") !== false)
		{
			$count++;
			$found = $p->name;
		}
	}
	if($count > 1)
		pm($me->name, "More than one player with the name '$search', using $found.");
	if(empty($count))
	{
		if(filetee($search, $me->name, $amount, false, false) == false)
		{
			global $file;
			$lines = file($file);
			foreach($lines as $line)
			{
				$pieces = explode(" ", $line); 
				if(stripos("$pieces[1]","$search") !== false)
				{
					$found = $pieces[1];
					$count++;
					break;
				}
			}
		}
	}
	if(empty($found) || empty($count) || filetee($found, $me->name, -2, false, false) === false)
	{
		pm($me->name, "No times found for player: $search");
		return;
	}
	filetee($found, $me->name, $amount, false, false);
}

function version($me)
{
	pm($me->name, "0xffff00Script programming by 0xffffffdukevin");
	pm($me->name, "0xffff00Email at 0xffffffdukevinjduke@gmail.com0xffff00 for suggestions, comments");
	pm($me->name, "0xffff00Made for smart's server");
}
/*
known bugs:
-respawn breaks script
-you should login to protect your times not showing
-times showed twise if time run out
-if you never won, top 3 won't show

		foreach($players as $p)
		{
			if(!(strstr($p->name, '@')))
				pm($p->name, "0xffddaaYou should /login to protect your times!");
		}

*/
?>