docker-tmserver/xaseco/plugins/plugin.localdatabase.php

1033 lines
38 KiB
PHP

<?php
/* vim: set noexpandtab tabstop=2 softtabstop=2 shiftwidth=2: */
/**
* This script saves record into a local database.
* You can modify this file as you want, to advance
* the information stored in the database!
*
* @author Florian Schnell
* @version 2.0
* Updated by Xymph
*
* Dependencies: requires plugin.panels.php on TMF
*/
Aseco::registerEvent('onStartup', 'ldb_loadSettings');
Aseco::registerEvent('onStartup', 'ldb_connect');
Aseco::registerEvent('onEverySecond', 'ldb_reconnect');
Aseco::registerEvent('onSync', 'ldb_sync');
Aseco::registerEvent('onNewChallenge', 'ldb_newChallenge');
Aseco::registerEvent('onPlayerConnect', 'ldb_playerConnect');
Aseco::registerEvent('onPlayerDisconnect', 'ldb_playerDisconnect');
Aseco::registerEvent('onPlayerFinish', 'ldb_playerFinish');
Aseco::registerEvent('onPlayerWins', 'ldb_playerWins');
// called @ onStartup
function ldb_loadSettings($aseco) {
global $ldb_settings;
$aseco->console('[LocalDB] Load config file [localdatabase.xml]');
if (!$settings = $aseco->xml_parser->parseXml('localdatabase.xml')) {
trigger_error('Could not read/parse Local database config file localdatabase.xml !', E_USER_ERROR);
}
$settings = $settings['SETTINGS'];
// read mysql server settings
$ldb_settings['mysql']['host'] = $settings['MYSQL_SERVER'][0];
$ldb_settings['mysql']['login'] = $settings['MYSQL_LOGIN'][0];
$ldb_settings['mysql']['password'] = $settings['MYSQL_PASSWORD'][0];
$ldb_settings['mysql']['database'] = $settings['MYSQL_DATABASE'][0];
$ldb_settings['mysql']['connection'] = false;
// display records in game?
if (strtoupper($settings['DISPLAY'][0]) == 'TRUE')
$ldb_settings['display'] = true;
else
$ldb_settings['display'] = false;
// set highest record still to be displayed
$ldb_settings['limit'] = $settings['LIMIT'][0];
$ldb_settings['messages'] = $settings['MESSAGES'][0];
} // ldb_loadSettings
// called @ onStartup
function ldb_connect($aseco) {
global $maxrecs;
// get the settings
global $ldb_settings;
// create data fields
global $ldb_records;
$ldb_records = new RecordList($maxrecs);
global $ldb_challenge;
$ldb_challenge = new Challenge();
// log status message
$aseco->console("[LocalDB] Try to connect to MySQL server on '{1}' with database '{2}'",
$ldb_settings['mysql']['host'], $ldb_settings['mysql']['database']);
if (!$ldb_settings['mysql']['connection'] = mysql_connect($ldb_settings['mysql']['host'],
$ldb_settings['mysql']['login'],
$ldb_settings['mysql']['password'])) {
trigger_error('[LocalDB] Could not authenticate at MySQL server!', E_USER_ERROR);
}
if (!mysql_select_db($ldb_settings['mysql']['database'])) {
trigger_error('[LocalDB] Could not find MySQL database!', E_USER_ERROR);
}
// log status message
$aseco->console('[LocalDB] MySQL Server Version is ' . mysql_get_server_info());
// optional UTF-8 handling fix
//mysql_query('SET NAMES utf8');
$aseco->console('[LocalDB] Checking database structure...');
// create main tables
$query = "CREATE TABLE IF NOT EXISTS `challenges` (
`Id` mediumint(9) NOT NULL auto_increment,
`Uid` varchar(27) NOT NULL default '',
`Date` datetime NOT NULL default '1970-01-01 00:00:00',
`Name` varchar(100) NOT NULL default '',
`Author` varchar(30) NOT NULL default '',
`Environment` varchar(10) NOT NULL default '',
`BronzeTime` int(11) NOT NULL default 0,
`SilverTime` int(11) NOT NULL default 0,
`GoldTime` int(11) NOT NULL default 0,
`AuthorTime` int(11) NOT NULL default 0,
PRIMARY KEY (`Id`),
UNIQUE KEY `Uid` (`Uid`)
) ENGINE=MyISAM";
mysql_query($query);
$query = "CREATE TABLE IF NOT EXISTS `players` (
`Id` mediumint(9) NOT NULL auto_increment,
`Login` varchar(50) NOT NULL default '',
`Game` varchar(3) NOT NULL default '',
`NickName` varchar(100) NOT NULL default '',
`Nation` varchar(3) NOT NULL default '',
`UpdatedAt` datetime NOT NULL default '1970-01-01 00:00:00',
`Wins` mediumint(9) NOT NULL default 0,
`TimePlayed` int(10) unsigned NOT NULL default 0,
`TeamName` char(60) NOT NULL default '',
PRIMARY KEY (`Id`),
UNIQUE KEY `Login` (`Login`),
KEY `Game` (`Game`)
) ENGINE=MyISAM";
mysql_query($query);
$query = "CREATE TABLE IF NOT EXISTS `records` (
`Id` int(11) NOT NULL auto_increment,
`ChallengeId` mediumint(9) NOT NULL default 0,
`PlayerId` mediumint(9) NOT NULL default 0,
`Score` int(11) NOT NULL default 0,
`Date` datetime NOT NULL default '1970-01-01 00:00:00',
`Checkpoints` text NOT NULL,
PRIMARY KEY (`Id`),
UNIQUE KEY `PlayerId` (`PlayerId`,`ChallengeId`),
KEY `ChallengeId` (`ChallengeId`)
) ENGINE=MyISAM";
mysql_query($query);
$query = "CREATE TABLE IF NOT EXISTS `players_extra` (
`playerID` mediumint(9) NOT NULL default 0,
`cps` smallint(3) NOT NULL default -1,
`dedicps` smallint(3) NOT NULL default -1,
`donations` mediumint(9) NOT NULL default 0,
`style` varchar(20) NOT NULL default '',
`panels` varchar(255) NOT NULL default '',
PRIMARY KEY (`playerID`),
KEY `donations` (`donations`)
) ENGINE=MyISAM";
mysql_query($query);
// check for main tables
$tables = array();
$res = mysql_query('SHOW TABLES');
while ($row = mysql_fetch_row($res))
$tables[] = $row[0];
mysql_free_result($res);
$check = array();
$check[1] = in_array('challenges', $tables);
$check[2] = in_array('players', $tables);
$check[3] = in_array('records', $tables);
$check[4] = in_array('players_extra', $tables);
if (!($check[1] && $check[2] && $check[3] && $check[4])) {
trigger_error('[LocalDB] Table structure incorrect! Use localdb/aseco.sql & extra.sql to correct this', E_USER_ERROR);
}
// enlarge challenges 'Name' colum
$result = mysql_query('DESC challenges Name');
$row = mysql_fetch_row($result);
mysql_free_result($result);
if ($row[1] != 'varchar(100)') {
$aseco->console("[LocalDB] Alter 'challenges' column 'Name'...");
mysql_query("ALTER TABLE challenges MODIFY Name varchar(100) NOT NULL default ''");
}
// reduce challenges 'Environment' colum
$result = mysql_query('DESC challenges Environment');
$row = mysql_fetch_row($result);
mysql_free_result($result);
if ($row[1] != 'varchar(10)') {
$aseco->console("[LocalDB] Alter 'challenges' column 'Environment'...");
mysql_query("ALTER TABLE challenges MODIFY Environment varchar(10) NOT NULL default ''");
}
// add players 'TeamName' column
$fields = array();
$result = mysql_query('SHOW COLUMNS FROM players');
while ($row = mysql_fetch_row($result))
$fields[] = $row[0];
mysql_free_result($result);
if (!in_array('TeamName', $fields)) {
$aseco->console("[LocalDB] Add 'players' column 'TeamName'...");
mysql_query("ALTER TABLE players ADD TeamName char(60) NOT NULL default ''");
}
// enlarge players 'NickName' & 'TimePlayed' columns
$result = mysql_query('DESC players NickName');
$row = mysql_fetch_row($result);
mysql_free_result($result);
if ($row[1] != 'varchar(100)') {
$aseco->console("[LocalDB] Alter 'players' column 'NickName'...");
mysql_query("ALTER TABLE players MODIFY NickName varchar(100) NOT NULL default ''");
}
$result = mysql_query('DESC players TimePlayed');
$row = mysql_fetch_row($result);
mysql_free_result($result);
if ($row[1] != 'int(10) unsigned') {
$aseco->console("[LocalDB] Alter 'players' column 'TimePlayed'...");
mysql_query("ALTER TABLE players MODIFY TimePlayed int(10) unsigned NOT NULL default 0");
}
// enlarge records 'Id' & 'Score' columns
$result = mysql_query('DESC records Id');
$row = mysql_fetch_row($result);
mysql_free_result($result);
if ($row[1] != 'int(11)') {
$aseco->console("[LocalDB] Alter 'records' column 'Id'...");
mysql_query('ALTER TABLE records MODIFY Id int(11) auto_increment');
}
$result = mysql_query('DESC records Score');
$row = mysql_fetch_row($result);
mysql_free_result($result);
if ($row[1] != 'int(11)') {
$aseco->console("[LocalDB] Alter 'records' column 'Score'...");
mysql_query("ALTER TABLE records MODIFY Score int(11) NOT NULL default 0");
}
// add records 'Checkpoints' column
$fields = array();
$result = mysql_query('SHOW COLUMNS FROM records');
while ($row = mysql_fetch_row($result))
$fields[] = $row[0];
mysql_free_result($result);
if (!in_array('Checkpoints', $fields)) {
$aseco->console("[LocalDB] Add 'records' column 'Checkpoints'...");
mysql_query("ALTER TABLE records ADD Checkpoints text NOT NULL");
}
// change records old 'ChallengeId' key into new 'PlayerId' key and
// add records new 'ChallengeId' key
$fields = array('PlayerId' => 0, 'ChallengeId' => 0);
$result = mysql_query('SHOW INDEX FROM records');
while ($row = mysql_fetch_row($result)) {
if (isset($fields[$row[2]]))
$fields[$row[2]]++;
}
mysql_free_result($result);
if ($fields['ChallengeId'] == 2 && $fields['PlayerId'] == 0) {
$aseco->console("[LocalDB] Drop 'records' key 'ChallengeId'...");
mysql_query("ALTER TABLE records DROP KEY ChallengeId");
$aseco->console("[LocalDB] Add 'records' key 'PlayerId'...");
mysql_query("ALTER TABLE records ADD UNIQUE KEY PlayerId (PlayerId, ChallengeId)");
$aseco->console("[LocalDB] Add 'records' key 'ChallengeId'...");
mysql_query("ALTER TABLE records ADD KEY ChallengeId (ChallengeId)");
}
// change players_extra 'playerID' key into primary key and
// add players_extra 'donations' key
$fields = array();
$result = mysql_query('SHOW INDEX FROM players_extra');
while ($row = mysql_fetch_row($result))
$fields[] = $row[2];
mysql_free_result($result);
if (in_array('playerID', $fields)) {
$aseco->console("[LocalDB] Drop 'players_extra' key 'playerID'...");
mysql_query("ALTER TABLE players_extra DROP KEY playerID");
}
if (!in_array('PRIMARY', $fields)) {
$aseco->console("[LocalDB] Add 'players_extra' primary key 'playerID'...");
mysql_query("ALTER TABLE players_extra ADD PRIMARY KEY (playerID)");
}
if (!in_array('donations', $fields)) {
$aseco->console("[LocalDB] Add 'players_extra' key 'donations'...");
mysql_query("ALTER TABLE players_extra ADD KEY donations (donations)");
}
$aseco->console('[LocalDB] ...Structure OK!');
} // ldb_connect
// called @ onEverySecond
function ldb_reconnect($aseco) {
global $ldb_settings;
// check if any players online
if (empty($aseco->server->players->player_list)) {
// check if MySQL connection still alive
if (!mysql_ping($ldb_settings['mysql']['connection'])) {
// connection timed out so reconnect
mysql_close($ldb_settings['mysql']['connection']);
if (!$ldb_settings['mysql']['connection'] = mysql_connect($ldb_settings['mysql']['host'],
$ldb_settings['mysql']['login'],
$ldb_settings['mysql']['password'])) {
trigger_error('[LocalDB] Could not authenticate at MySQL server!', E_USER_ERROR);
}
if (!mysql_select_db($ldb_settings['mysql']['database'])) {
trigger_error('[LocalDB] Could not find MySQL database!', E_USER_ERROR);
}
$aseco->console('[LocalDB] Reconnected to MySQL Server');
}
}
} // ldb_reconnect
// called @ onSync
function ldb_sync($aseco) {
/* ldb_playerConnect on sync already invoked via onPlayerConnect event,
so disable it here - Xymph
$aseco->console('[LocalDB] Synchronize players with database');
// take each player in the list and simulate a join
while ($player = $aseco->server->players->nextPlayer()) {
// log debug message
if ($aseco->debug) $aseco->console('[LocalDB] Sending player ' . $player->login);
ldb_playerConnect($aseco, $player);
}
disabled */
// reset player list
$aseco->server->players->resetPlayers();
} // ldb_sync
// called @ onPlayerConnect
function ldb_playerConnect($aseco, $player) {
global $ldb_settings;
if ($aseco->server->getGame() == 'TMF')
$nation = mapCountry($player->nation);
else // TMN/TMS/TMO
$nation = $player->nation;
// get player stats
$query = 'SELECT Id, Wins, TimePlayed, TeamName FROM players
WHERE Login=' . quotedString($player->login); // .
// ' AND Game=' . quotedString($aseco->server->getGame());
$result = mysql_query($query);
if ($result === false || mysql_num_rows($result) === false) {
if ($result !== false)
mysql_free_result($result);
trigger_error('Could not get stats of connecting player! (' . mysql_error() . ')' . CRLF . 'sql = ' . $query, E_USER_WARNING);
return;
}
// was retrieved
if (mysql_num_rows($result) > 0) {
$dbplayer = mysql_fetch_object($result);
mysql_free_result($result);
// update player stats
$player->id = $dbplayer->Id;
if ($player->teamname == '' && $dbplayer->TeamName != '') {
$player->teamname = $dbplayer->TeamName;
}
if ($player->wins < $dbplayer->Wins) {
$player->wins = $dbplayer->Wins;
}
if ($player->timeplayed < $dbplayer->TimePlayed) {
$player->timeplayed = $dbplayer->TimePlayed;
}
// update player data
$query = 'UPDATE players
SET NickName=' . quotedString(stripColors($player->nickname)) . ',
Nation=' . quotedString($nation) . ',
TeamName=' . quotedString($player->teamname) . ',
UpdatedAt=NOW()
WHERE Login=' . quotedString($player->login); // .
// ' AND Game=' . quotedString($aseco->server->getGame());
$result = mysql_query($query);
if ($result === false || mysql_affected_rows() == -1) {
trigger_error('Could not update connecting player! (' . mysql_error() . ')' . CRLF . 'sql = ' . $query, E_USER_WARNING);
return;
}
// could not be retrieved
} else { // mysql_num_rows() == 0
mysql_free_result($result);
$player->id = 0;
// insert player
$query = 'INSERT INTO players
(Login, Game, NickName, Nation, TeamName, UpdatedAt)
VALUES
(' . quotedString($player->login) . ', ' .
quotedString($aseco->server->getGame()) . ', ' .
quotedString(stripColors($player->nickname)) . ', ' .
quotedString($nation) . ', ' .
quotedString($player->teamname) . ', NOW())';
$result = mysql_query($query);
if ($result === false || mysql_affected_rows() != 1) {
trigger_error('Could not insert connecting player! (' . mysql_error() . ')' . CRLF . 'sql = ' . $query, E_USER_WARNING);
return;
} else {
$query = 'SELECT LAST_INSERT_ID() FROM players';
$result = mysql_query($query);
if ($result === false || mysql_num_rows($result) === false) {
if ($result !== false)
mysql_free_result($result);
trigger_error('Could not get inserted player\'s id! (' . mysql_error() . ')' . CRLF . 'sql = ' . $query, E_USER_WARNING);
return;
} else {
$dbplayer = mysql_fetch_row($result);
$player->id = $dbplayer[0];
mysql_free_result($result);
}
}
}
// check for player's extra data
$query = 'SELECT playerID FROM players_extra
WHERE playerID=' . $player->id;
$result = mysql_query($query);
if ($result === false || mysql_num_rows($result) === false) {
if ($result !== false)
mysql_free_result($result);
trigger_error('Could not get player\'s extra data! (' . mysql_error() . ')' . CRLF . 'sql = ' . $query, E_USER_WARNING);
return;
}
// was retrieved
if (mysql_num_rows($result) > 0) {
mysql_free_result($result);
// could not be retrieved
} else { // mysql_num_rows() == 0
mysql_free_result($result);
// insert player's default extra data
$query = 'INSERT INTO players_extra
(playerID, cps, dedicps, donations, style, panels)
VALUES
(' . $player->id . ', ' .
($aseco->settings['auto_enable_cps'] ? 0 : -1) . ', ' .
($aseco->settings['auto_enable_dedicps'] ? 0 : -1) . ', 0, ' .
quotedString($aseco->settings['window_style']) . ', ' .
quotedString($aseco->settings['admin_panel'] . '/' .
$aseco->settings['donate_panel'] . '/' .
$aseco->settings['records_panel'] . '/' .
$aseco->settings['vote_panel']) . ')';
$result = mysql_query($query);
if ($result === false || mysql_affected_rows() != 1) {
trigger_error('Could not insert player\'s extra data! (' . mysql_error() . ')' . CRLF . 'sql = ' . $query, E_USER_WARNING);
}
}
} // ldb_playerConnect
// called @ onPlayerDisconnect
function ldb_playerDisconnect($aseco, $player) {
// ignore fluke disconnects with empty logins
if ($player->login == '') return;
// update player
$query = 'UPDATE players
SET UpdatedAt=NOW(),
TimePlayed=TimePlayed+' . $player->getTimeOnline() . '
WHERE Login=' . quotedString($player->login); // .
// ' AND Game=' . quotedString($aseco->server->getGame());
$result = mysql_query($query);
if ($result === false || mysql_affected_rows() == -1) {
trigger_error('Could not update disconnecting player! (' . mysql_error() . ')' . CRLF . 'sql = ' . $query, E_USER_WARNING);
}
} // ldb_playerDisconnect
function ldb_getDonations($aseco, $login) {
// get player's donations
$query = 'SELECT donations FROM players_extra
WHERE playerID=' . $aseco->getPlayerId($login);
$result = mysql_query($query);
if ($result === false || mysql_num_rows($result) === false || mysql_num_rows($result) == 0) {
if ($result !== false)
mysql_free_result($result);
trigger_error('Could not get player\'s donations! (' . mysql_error() . ')' . CRLF . 'sql = ' . $query, E_USER_WARNING);
return false;
} else {
$dbextra = mysql_fetch_object($result);
mysql_free_result($result);
return $dbextra->donations;
}
} // ldb_getDonations
function ldb_updateDonations($aseco, $login, $donation) {
// update player's donations
$query = 'UPDATE players_extra
SET donations=donations+' . $donation . '
WHERE playerID=' . $aseco->getPlayerId($login);
$result = mysql_query($query);
if ($result === false || mysql_affected_rows() != 1) {
trigger_error('Could not update player\'s donations! (' . mysql_error() . ')' . CRLF . 'sql = ' . $query, E_USER_WARNING);
}
} // ldb_updateDonations
function ldb_getCPs($aseco, $login) {
// get player's CPs settings
$query = 'SELECT cps, dedicps FROM players_extra
WHERE playerID=' . $aseco->getPlayerId($login);
$result = mysql_query($query);
if ($result === false || mysql_num_rows($result) === false || mysql_num_rows($result) == 0) {
if ($result !== false)
mysql_free_result($result);
trigger_error('Could not get player\'s CPs! (' . mysql_error() . ')' . CRLF . 'sql = ' . $query, E_USER_WARNING);
return false;
} else {
$dbextra = mysql_fetch_object($result);
mysql_free_result($result);
return array('cps' => $dbextra->cps, 'dedicps' => $dbextra->dedicps);
}
} // ldb_getCPs
function ldb_setCPs($aseco, $login, $cps, $dedicps) {
$query = 'UPDATE players_extra
SET cps=' . $cps . ', dedicps=' . $dedicps . '
WHERE playerID=' . $aseco->getPlayerId($login);
$result = mysql_query($query);
if ($result === false || mysql_affected_rows() == -1) {
trigger_error('Could not update player\'s CPs! (' . mysql_error() . ')' . CRLF . 'sql = ' . $query, E_USER_WARNING);
}
} // ldb_setCPs
function ldb_getStyle($aseco, $login) {
// get player's style
$query = 'SELECT style FROM players_extra
WHERE playerID=' . $aseco->getPlayerId($login);
$result = mysql_query($query);
if ($result === false || mysql_num_rows($result) === false || mysql_num_rows($result) == 0) {
if ($result !== false)
mysql_free_result($result);
trigger_error('Could not get player\'s style! (' . mysql_error() . ')' . CRLF . 'sql = ' . $query, E_USER_WARNING);
return false;
} else {
$dbextra = mysql_fetch_object($result);
mysql_free_result($result);
return $dbextra->style;
}
} // ldb_getStyle
function ldb_setStyle($aseco, $login, $style) {
$query = 'UPDATE players_extra
SET style=' . quotedString($style) . '
WHERE playerID=' . $aseco->getPlayerId($login);
$result = mysql_query($query);
if ($result === false || mysql_affected_rows() == -1) {
trigger_error('Could not update player\'s style! (' . mysql_error() . ')' . CRLF . 'sql = ' . $query, E_USER_WARNING);
}
} // ldb_setStyle
function ldb_getPanels($aseco, $login) {
// get player's panels
$query = 'SELECT panels FROM players_extra
WHERE playerID=' . $aseco->getPlayerId($login);
$result = mysql_query($query);
if ($result === false || mysql_num_rows($result) === false || mysql_num_rows($result) == 0) {
if ($result !== false)
mysql_free_result($result);
trigger_error('Could not get player\'s panels! (' . mysql_error() . ')' . CRLF . 'sql = ' . $query, E_USER_WARNING);
return false;
} else {
$dbextra = mysql_fetch_object($result);
mysql_free_result($result);
$panel = explode('/', $dbextra->panels);
$panels = array();
$panels['admin'] = $panel[0];
$panels['donate'] = $panel[1];
$panels['records'] = $panel[2];
$panels['vote'] = $panel[3];
return $panels;
}
} // ldb_getPanels
function ldb_setPanel($aseco, $login, $type, $panel) {
// update player's panels
$panels = ldb_getPanels($aseco, $login);
$panels[$type] = $panel;
$query = 'UPDATE players_extra
SET panels=' . quotedString($panels['admin'] . '/' . $panels['donate'] . '/' .
$panels['records'] . '/' . $panels['vote']) . '
WHERE playerID=' . $aseco->getPlayerId($login);
$result = mysql_query($query);
if ($result === false || mysql_affected_rows() == -1) {
trigger_error('Could not update player\'s panels! (' . mysql_error() . ')' . CRLF . 'sql = ' . $query, E_USER_WARNING);
}
} // ldb_setPanel
// called @ onPlayerFinish
function ldb_playerFinish($aseco, $finish_item) {
global $ldb_records, $ldb_settings,
$checkpoints; // from plugin.checkpoints.php
// if no actual finish, bail out immediately
if ($finish_item->score == 0) return;
// in Laps mode on real PlayerFinish event, bail out too
if ($aseco->server->gameinfo->mode == Gameinfo::LAPS && !$finish_item->new) return;
$login = $finish_item->player->login;
$nickname = stripColors($finish_item->player->nickname);
// reset lap 'Finish' flag & add checkpoints
$finish_item->new = false;
$finish_item->checks = (isset($checkpoints[$login]) ? $checkpoints[$login]->curr_cps : array());
// drove a new record?
// go through each of the XX records
for ($i = 0; $i < $ldb_records->max; $i++) {
$cur_record = $ldb_records->getRecord($i);
// if player's time/score is better, or record isn't set (thanks eyez)
if ($cur_record === false || ($aseco->server->gameinfo->mode == Gameinfo::STNT ?
$finish_item->score > $cur_record->score :
$finish_item->score < $cur_record->score)) {
// does player have a record already?
$cur_rank = -1;
$cur_score = 0;
for ($rank = 0; $rank < $ldb_records->count(); $rank++) {
$rec = $ldb_records->getRecord($rank);
if ($rec->player->login == $login) {
// new record worse than old one
if ($aseco->server->gameinfo->mode == Gameinfo::STNT ?
$finish_item->score < $rec->score :
$finish_item->score > $rec->score) {
return;
// new record is better than or equal to old one
} else {
$cur_rank = $rank;
$cur_score = $rec->score;
break;
}
}
}
$finish_time = $finish_item->score;
if ($aseco->server->gameinfo->mode != Gameinfo::STNT)
$finish_time = formatTime($finish_time);
if ($cur_rank != -1) { // player has a record in topXX already
// compute difference to old record
if ($aseco->server->gameinfo->mode != Gameinfo::STNT) {
$diff = $cur_score - $finish_item->score;
$sec = floor($diff/1000);
$hun = ($diff - ($sec * 1000)) / 10;
} else { // Stunts
$diff = $finish_item->score - $cur_score;
}
// update record if improved
if ($diff > 0) {
$finish_item->new = true;
$ldb_records->setRecord($cur_rank, $finish_item);
}
// player moved up in LR list
if ($cur_rank > $i) {
// move record to the new position
$ldb_records->moveRecord($cur_rank, $i);
// do a player improved his/her LR rank message
$message = formatText($ldb_settings['messages']['RECORD_NEW_RANK'][0],
$nickname,
$i+1,
($aseco->server->gameinfo->mode == Gameinfo::STNT ? 'Score' : 'Time'),
$finish_time,
$cur_rank+1,
($aseco->server->gameinfo->mode == Gameinfo::STNT ?
'+' . $diff : sprintf('-%d.%02d', $sec, $hun)));
// show chat message to all or player
if ($ldb_settings['display']) {
if ($i < $ldb_settings['limit']) {
if ($aseco->settings['recs_in_window'] && function_exists('send_window_message'))
send_window_message($aseco, $message, false);
else
$aseco->client->query('ChatSendServerMessage', $aseco->formatColors($message));
} else {
$message = str_replace('{#server}>> ', '{#server}> ', $message);
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
}
}
} else {
if ($diff == 0) {
// do a player equaled his/her record message
$message = formatText($ldb_settings['messages']['RECORD_EQUAL'][0],
$nickname,
$cur_rank+1,
($aseco->server->gameinfo->mode == Gameinfo::STNT ? 'Score' : 'Time'),
$finish_time);
} else {
// do a player secured his/her record message
$message = formatText($ldb_settings['messages']['RECORD_NEW'][0],
$nickname,
$i+1,
($aseco->server->gameinfo->mode == Gameinfo::STNT ? 'Score' : 'Time'),
$finish_time,
$cur_rank+1,
($aseco->server->gameinfo->mode == Gameinfo::STNT ?
'+' . $diff : sprintf('-%d.%02d', $sec, $hun)));
}
// show chat message to all or player
if ($ldb_settings['display']) {
if ($i < $ldb_settings['limit']) {
if ($aseco->settings['recs_in_window'] && function_exists('send_window_message'))
send_window_message($aseco, $message, false);
else
$aseco->client->query('ChatSendServerMessage', $aseco->formatColors($message));
} else {
$message = str_replace('{#server}>> ', '{#server}> ', $message);
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
}
}
}
} else { // player hasn't got a record yet
// if previously tracking own/last local record, now track new one
if (isset($checkpoints[$login]) &&
$checkpoints[$login]->loclrec == 0 && $checkpoints[$login]->dedirec == -1) {
$checkpoints[$login]->best_fin = $checkpoints[$login]->curr_fin;
$checkpoints[$login]->best_cps = $checkpoints[$login]->curr_cps;
}
// insert new record at the specified position
$finish_item->new = true;
$ldb_records->addRecord($finish_item, $i);
// do a player drove first record message
$message = formatText($ldb_settings['messages']['RECORD_FIRST'][0],
$nickname,
$i+1,
($aseco->server->gameinfo->mode == Gameinfo::STNT ? 'Score' : 'Time'),
$finish_time);
// show chat message to all or player
if ($ldb_settings['display']) {
if ($i < $ldb_settings['limit']) {
if ($aseco->settings['recs_in_window'] && function_exists('send_window_message'))
send_window_message($aseco, $message, false);
else
$aseco->client->query('ChatSendServerMessage', $aseco->formatColors($message));
} else {
$message = str_replace('{#server}>> ', '{#server}> ', $message);
$aseco->client->query('ChatSendServerMessageToLogin', $aseco->formatColors($message), $login);
}
}
}
// update aseco records
$aseco->server->records = $ldb_records;
// log records when debugging is set to true
//if ($aseco->debug) $aseco->console('ldb_playerFinish records:' . CRLF . print_r($ldb_records, true));
// insert and log a new local record (not an equalled one)
if ($finish_item->new) {
ldb_insert_record($finish_item);
// update all panels if new #1 record
if ($aseco->server->getGame() == 'TMF' && $i == 0) {
setRecordsPanel('local', ($aseco->server->gameinfo->mode == Gameinfo::STNT ?
str_pad($finish_item->score, 5, ' ', STR_PAD_LEFT) :
formatTime($finish_item->score)));
if (function_exists('update_allrecpanels'))
update_allrecpanels($aseco, null); // from plugin.panels.php
}
// log record message in console
$aseco->console('[LocalDB] player {1} finished with {2} and took the {3}. LR place!',
$login, $finish_item->score, $i+1);
// throw 'local record' event
$finish_item->pos = $i+1;
$aseco->releaseEvent('onLocalRecord', $finish_item);
}
// got the record, now stop!
return;
}
}
} // ldb_playerFinish
function ldb_insert_record($record) {
global $aseco, $ldb_challenge;
$playerid = $record->player->id;
$cps = implode(',', $record->checks);
// insert new record or update existing
$query = 'INSERT INTO records
(ChallengeId, PlayerId, Score, Date, Checkpoints)
VALUES
(' . $ldb_challenge->id . ', ' . $playerid . ', ' .
$record->score . ', NOW(), ' . quotedString($cps) . ') ' .
'ON DUPLICATE KEY UPDATE ' .
'Score=VALUES(Score), Date=VALUES(Date), Checkpoints=VALUES(Checkpoints)';
$result = mysql_query($query);
if ($result === false || mysql_affected_rows() <= 0) {
trigger_error('Could not insert/update record! (' . mysql_errno() . ': ' . mysql_error() . ')' . CRLF . 'sql = ' . $query, E_USER_WARNING);
}
} // ldb_insert_record
function ldb_removeRecord($aseco, $cid, $pid, $recno) {
global $ldb_records;
// remove record
$query = 'DELETE FROM records WHERE ChallengeId=' . $cid . ' AND PlayerId=' . $pid;
$result = mysql_query($query);
if ($result === false || mysql_affected_rows() != 1) {
trigger_error('Could not remove record! (' . mysql_error() . ')' . CRLF . 'sql = ' . $query, E_USER_WARNING);
}
// remove record from specified position
$ldb_records->delRecord($recno);
// check if fill up is needed
if ($ldb_records->count() == ($ldb_records->max - 1)) {
// get max'th time
$query = 'SELECT DISTINCT playerid,score FROM rs_times t1 WHERE challengeid=' . $cid .
' AND score=(SELECT MIN(t2.score) FROM rs_times t2 WHERE challengeid=' . $cid .
' AND t1.playerid=t2.playerid) ORDER BY score,date LIMIT ' . ($ldb_records->max - 1) . ',1';
$result = mysql_query($query);
if ($result !== false && mysql_num_rows($result) == 1) {
$timerow = mysql_fetch_object($result);
// get corresponding date/time & checkpoints
$query = 'SELECT date,checkpoints FROM rs_times WHERE challengeid=' . $cid .
' AND playerid=' . $timerow->playerid . ' ORDER BY score,date LIMIT 1';
$result2 = mysql_query($query);
$timerow2 = mysql_fetch_object($result2);
$datetime = date('Y-m-d H:i:s', $timerow2->date);
mysql_free_result($result2);
// insert/update new max'th record
$query = 'INSERT INTO records
(ChallengeId, PlayerId, Score, Date, Checkpoints)
VALUES
(' . $cid . ', ' . $timerow->playerid . ', ' .
$timerow->score . ', ' . quotedString($datetime) . ', ' .
quotedString($timerow2->checkpoints) . ') ' .
'ON DUPLICATE KEY UPDATE ' .
'Score=VALUES(Score), Date=VALUES(Date), Checkpoints=VALUES(Checkpoints)';
$result2 = mysql_query($query);
if ($result2 === false || mysql_affected_rows() <= 0) {
trigger_error('Could not insert/update record! (' . mysql_errno() . ': ' . mysql_error() . ')' . CRLF . 'sql = ' . $query, E_USER_WARNING);
}
// get player info
$query = 'SELECT * FROM players WHERE id=' . $timerow->playerid;
$result2 = mysql_query($query);
$playrow = mysql_fetch_array($result2);
mysql_free_result($result2);
// create record object
$record_item = new Record();
$record_item->score = $timerow->score;
$record_item->checks = ($timerow2->checkpoints != '' ? explode(',', $timerow2->checkpoints) : array());
$record_item->new = false;
// create a player object to put it into the record object
$player_item = new Player();
$player_item->nickname = stripColors($playrow['NickName']);
$player_item->login = $playrow['Login'];
$record_item->player = $player_item;
// add the track information to the record object
$record_item->challenge = clone $aseco->server->challenge;
unset($record_item->challenge->gbx); // reduce memory usage
unset($record_item->challenge->tmx);
// add the created record to the list
$ldb_records->addRecord($record_item);
}
if ($result !== false)
mysql_free_result($result);
}
// update aseco records
$aseco->server->records = $ldb_records;
} // ldb_remove_record
// called @ onNewChallenge
function ldb_newChallenge($aseco, $challenge) {
global $ldb_challenge, $ldb_records, $ldb_settings;
$ldb_records->clear();
$aseco->server->records->clear();
// on relay, ignore master server's challenge
if ($aseco->server->isrelay) {
$challenge->id = 0;
return;
}
$order = ($aseco->server->gameinfo->mode == Gameinfo::STNT ? 'DESC' : 'ASC');
$query = 'SELECT c.Id AS ChallengeId, r.Score, p.NickName, p.Login, r.Date, r.Checkpoints
FROM challenges c
LEFT JOIN records r ON (r.ChallengeId=c.Id)
LEFT JOIN players p ON (r.PlayerId=p.Id)
WHERE c.Uid=' . quotedString($challenge->uid) . '
GROUP BY r.Id
ORDER BY r.Score ' . $order . ',r.Date ASC
LIMIT ' . $ldb_records->max;
$result = mysql_query($query);
if ($result === false || mysql_num_rows($result) === false) {
if ($result !== false)
mysql_free_result($result);
trigger_error('Could not get challenge info! (' . mysql_error() . ')' . CRLF . 'sql = ' . $query, E_USER_WARNING);
return;
}
// challenge found?
if (mysql_num_rows($result) > 0) {
// get each record
while ($record = mysql_fetch_array($result)) {
// create record object
$record_item = new Record();
$record_item->score = $record['Score'];
$record_item->checks = ($record['Checkpoints'] != '' ? explode(',', $record['Checkpoints']) : array());
$record_item->new = false;
// create a player object to put it into the record object
$player_item = new Player();
$player_item->nickname = stripColors($record['NickName']);
$player_item->login = $record['Login'];
$record_item->player = $player_item;
// add the track information to the record object
$record_item->challenge = clone $challenge;
unset($record_item->challenge->gbx); // reduce memory usage
unset($record_item->challenge->tmx);
// add the created record to the list
$ldb_records->addRecord($record_item);
// get challenge info
$ldb_challenge->id = $record['ChallengeId'];
$challenge->id = $record['ChallengeId'];
}
// update aseco records
$aseco->server->records = $ldb_records;
// log records when debugging is set to true
//if ($aseco->debug) $aseco->console('ldb_newChallenge records:' . CRLF . print_r($ldb_records, true));
mysql_free_result($result);
// challenge isn't in database yet
} else {
mysql_free_result($result);
// then create it
$query = 'INSERT INTO challenges
(Uid, Name, Author, Environment, BronzeTime, SilverTime, GoldTime, AuthorTime)
VALUES
(' . quotedString($challenge->uid) . ', ' .
quotedString(stripColors($challenge->name)) . ', ' .
quotedString($challenge->author) . ', ' .
quotedString($challenge->environment) . ', ' .
quotedString($challenge->bronzetime) . ', ' .
quotedString($challenge->silvertime) . ', ' .
quotedString($challenge->goldtime) . ', ' .
quotedString($challenge->authortime) . ')';
$result = mysql_query($query);
// challenge was inserted successfully
if ($result !== false && mysql_affected_rows() == 1) {
// get its Id now
$query = 'SELECT Id FROM challenges
WHERE Uid=' . quotedString($challenge->uid);
$result = mysql_query($query);
if ($result !== false && mysql_num_rows($result) == 1) {
$row = mysql_fetch_row($result);
$ldb_challenge->id = $row[0];
$challenge->id = $row[0];
} else {
// challenge Id could not be found
trigger_error('Could not get new challenge id! (' . mysql_error() . ')' . CRLF . 'sql = ' . $query, E_USER_WARNING);
}
if ($result !== false)
mysql_free_result($result);
} else {
trigger_error('Could not insert new challenge! (' . mysql_error() . ')' . CRLF . 'sql = ' . $query, E_USER_WARNING);
}
}
} // ldb_newChallenge
// called @ onPlayerWins
function ldb_playerWins($aseco, $player) {
$wins = $player->getWins();
$query = 'UPDATE players
SET Wins=' . $wins . '
WHERE Login=' . quotedString($player->login);
$result = mysql_query($query);
if ($result === false || mysql_affected_rows() != 1) {
trigger_error('Could not update winning player! (' . mysql_error() . ')' . CRLF . 'sql = ' . $query, E_USER_WARNING);
}
} // ldb_playerWins
?>