<?php

/*
 * Plugin: Nickname Sync
 * ~~~~~~~~~~~~~~~~~~~~~
 * This Plugin synchronizes the Nicknames of Players in your localdatabase with
 * Nicknames from DedimaniaRecords, GerymaniaRecords.
 *
 * ----------------------------------------------------------------------------------
 * Author:		undef.de
 * Original Author:	.anDy
 * Version:		1.2.0
 * Date:		2011-12-04
 * Copyright:		2011 by .anDy and undef.de
 * Home:		http://labs.undef.de/
 * System:		XAseco2/0.95+
 * Game:		Trackmania2 (ManiaPlanet)
 * ----------------------------------------------------------------------------------
 *
 * LICENSE: This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as published
 * by the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 *
 * ----------------------------------------------------------------------------------
 *
 * Dependencies:
 *  - plugins/plugin.localdatabase.php		Required, for Datasbase access and Local-Records-Widget
 *  - plugins/plugin.dedimania.php		Required, only if you want the Dedimania-Sync
 *  - plugins/plugin.gerymania.php		Required, only if you want the Gerymania-Sync (only for Gamemode 'Stunts'. Get it here: http://www.tm-forum.com/viewtopic.php?f=127&t=27398)
 *
 */


Aseco::registerEvent('onSync',			'ns_onSync');
Aseco::registerEvent('onEverySecond',		'ns_onEverySecond');
Aseco::registerEvent('onBeginMap2',		'ns_onBeginMap2');


global $ns_config;


/*
#///////////////////////////////////////////////////////////////////////#
#									#
#///////////////////////////////////////////////////////////////////////#
*/

// called @ onSync
function ns_onSync ($aseco) {
	global $ns_config;


	// Check for the right XAseco2-Version
	$xaseco2_min_version = 0.95;
	if ( defined('XASECO2_VERSION') ) {
		if ( version_compare(XASECO2_VERSION, $xaseco2_min_version, '<') ) {
			trigger_error('[plugin.nickname_sync.php] Not supported XAseco2 version ('. XASECO2_VERSION .')! Please update to min. version '. $xaseco2_min_version .'!', E_USER_ERROR);
		}
	}
	else {
		trigger_error('[plugin.nickname_sync.php] Can not identify the System, "XASECO2_VERSION" is unset! This plugin runs only with XAseco2/'. $xaseco2_min_version .'+', E_USER_ERROR);
	}

	if ($aseco->server->getGame() != 'MP') {
		trigger_error('[plugin.nickname_sync.php] This plugin supports only TM2 (ManiaPlanet), can not start with a "'. $aseco->server->getGame() .'" Dedicated-Server!', E_USER_ERROR);
	}


	// Check for required plugins
	$required = array('plugin.localdatabase.php' => true);
	foreach ($required as $plugin => &$state) {
		foreach ($aseco->plugins as $installed_plugin) {
			if ($plugin == $installed_plugin) {
				// Found, skip to next plugin
				continue 2;
			}
		}
		trigger_error('[plugin.nickname_sync.php] Unmet requirements! You need to activate "' . $plugin . '" in your "plugins.xml" to run this Plugin!', E_USER_ERROR);
	}


	// Check for optional plugins
	$optional = array(
		'plugin.dedimania.php'		=> true,
		'plugin.gerymania.php'		=> true
	);
	$optionalCount = 0;
	foreach ($optional as $plugin => &$state) {
		$ns_config['Plugins'][$plugin] = false;			// Auto off, turn on if found
		foreach ($aseco->plugins as &$installed_plugin) {
			if ($plugin == $installed_plugin) {
				$ns_config['Plugins'][$plugin] = true;
				// Found, skip to next plugin
				continue 2;
			}
		}
		unset($installed_plugin);
		$optionalCount++;
	}
	unset($state);
	if (count($optional) == $optionalCount) {
		trigger_error('[plugin.nickname_sync.php] Plugin is currently useless! You need to activate "' . implode('" or "', array_keys($optional)) . '" in your "plugins.xml" to run this Plugin!', E_USER_WARNING);
		$ns_config['SyncNicknames'] = false;
	}
	else {
		$ns_config['SyncNicknames'] = true;
	}

	// Register this to the global version pool (for up-to-date checks)
	$aseco->plugin_versions[] = array(
		'plugin'	=> 'plugin.nickname_sync.php',
		'author'	=> 'undef.de',
		'version'	=> '1.2.0'
	);

	$ns_config['RefreshInterval'] = 5;
	$ns_config['RefreshTimestamp'] = (time()*2);			// Do not refresh now, refresh only after onBeginMap2!
}

/*
#///////////////////////////////////////////////////////////////////////#
#									#
#///////////////////////////////////////////////////////////////////////#
*/

// called @ onEverySecond
// $dedi_db is imported from plugin.dedimania.php
// $gery_db is imported from plugin.gerymania.php
function ns_onEverySecond ($aseco) {
	global $ns_config, $dedi_db, $gery_db;


	if ( ($ns_config['SyncNicknames'] == true) && (time() >= $ns_config['RefreshTimestamp']) ) {

		// Set next refresh Timestamp
		$ns_config['RefreshTimestamp'] = (time() + $ns_config['RefreshInterval']);

		if ( ($ns_config['Sync']['Gerymania'] == true) && ($aseco->server->gameinfo->mode == 6) ) {
			// On Stuntmode compare with GerymaniaRecords
			if ( !empty($gery_db) ) {
				ns_comparePlayers($gery_db, 'login', 'nick');

				// Mark updated
				$ns_config['Sync']['Gerymania'] = false;
			}
		}
		else {
			// On other Gamemodes compare with DedimaniaRecords or ManiaRecords
			if ( ($ns_config['Sync']['Dedimania'] == true) && (isset($dedi_db['Challenge']['Records'])) ) {
				ns_comparePlayers($dedi_db['Challenge']['Records'], 'Login', 'NickName');

				// Mark updated
				$ns_config['Sync']['Dedimania'] = false;
			}
		}
	}
}

/*
#///////////////////////////////////////////////////////////////////////#
#									#
#///////////////////////////////////////////////////////////////////////#
*/

// called @ onBeginMap2
function ns_onBeginMap2 ($aseco) {
	global $ns_config;


	// Auto off, turn on if releated Plugin is enabled
	$ns_config['Sync']['Dedimania'] = false;
	$ns_config['Sync']['Gerymania'] = false;

	// Enable the Sync if enabled
	if ($ns_config['Plugins']['plugin.dedimania.php'] == true) {
		$ns_config['Sync']['Dedimania'] = true;
	}
	if ($ns_config['Plugins']['plugin.gerymania.php'] == true) {
		$ns_config['Sync']['Gerymania'] = true;
	}
	$ns_config['RefreshTimestamp'] = time();
}

/*
#///////////////////////////////////////////////////////////////////////#
#									#
#///////////////////////////////////////////////////////////////////////#
*/

function ns_comparePlayers ($publics, $keyLogin, $keyNick) {
	global $aseco;


	$playersToUpdate = array();
	$playersUnknownPublic = array();
	foreach ($publics as &$public) {

		// Check if Player is currently on Server
		if (isset($aseco->server->players->player_list[$public[$keyLogin]])) {
			// Player is online, no action
			continue;
		}

		// Search Nickname of Player in local Records
		foreach ($aseco->server->records->record_list as &$local) {
			if ($local->player->login == $public[$keyLogin]) {
				// Check for different Nickname
				if ($local->player->nickname != $public[$keyNick]) {
					// Update Nickname in local Records (impermanent, only for showing new Nickname in Widgets)
					$local->player->nickname = $public[$keyNick];
					// Add it to the update list to make this Nickname permament
					$playersToUpdate[$public[$keyLogin]] = $public[$keyNick];
				}
				continue 2;
			}
		}

		// Nickname not found, cache it for database search
		$playersUnknownPublic[$public[$keyLogin]] = $public[$keyNick];
		continue;
	}
	unset($public, $local);

	if (count($playersUnknownPublic) > 0) {

		// Check if Players exists on database
		$playersKnownLocal = ns_getPlayers($playersUnknownPublic);

		foreach ($playersKnownLocal as $login => &$nick) {
			// Check for different Nickname
			if ($playersUnknownPublic[$login] != $nick) {
				// Add it to update list to make it permament
				$playersToUpdate[$login] = $playersUnknownPublic[$login];
			}
		}
		unset($playersKnownLocal, $nick);
	}
	unset($playersUnknownPublic);

	// Update all new Nicknames to Databases
	ns_updatePlayers($playersToUpdate);
}

/*
#///////////////////////////////////////////////////////////////////////#
#									#
#///////////////////////////////////////////////////////////////////////#
*/

function ns_updatePlayers ($players) {
	global $aseco;


	if (count($players) > 0) {
		$aseco->console("[plugin.nickname_sync.php] Update Nicknames of " . implode(", ", array_keys($players)));

		foreach ($players as $login => &$nick) {
			// Update Player Nickname
			$query = "UPDATE `players` SET `NickName`='". mysql_real_escape_string($nick) ."' WHERE `Login`='". mysql_real_escape_string($login) ."';";
			$result = mysql_query($query);

			if (mysql_affected_rows() == -1) {
				trigger_error('[plugin.nickname_sync.php] Could not update Player by public Database! ('. mysql_error() .')'. CRLF .'sql = '. $query, E_USER_WARNING);
			}
		}
		unset($nick);
	}
}

/*
#///////////////////////////////////////////////////////////////////////#
#									#
#///////////////////////////////////////////////////////////////////////#
*/

function ns_getPlayers ($players) {


	// Find Players from Players-Array in Database
	$players = array();
	$query = "SELECT `Login`,`NickName` FROM `players` WHERE `Login` IN ('". implode("','", array_keys($players)) ."');";

	$result = mysql_query($query);
	if ($result) {
		if (mysql_num_rows($result) > 0) {
			while ($row = mysql_fetch_row($result)) {
				// row[0] = Login, row[1] = Nickname
				$players[$row[0]] = $row[1];
			}
		}

		// Free up the results
		mysql_free_result($result);
	}

	return $players;
}

?>
