<form>
<?php
include("../config.php3");
include($BIB."bib_generic.php3");
include($BIB."bib_cheat.php3");

####################
# Administration script defaults
####################
# pas de timeout possible qql soit l'action effectuée
set_time_limit($TIME_LIMIT);

# le script continue une fois qu'il est lancé qql soit l'état de la connection après
ignore_user_abort(true); 
?>
<html>
<head></head>
<link rel="stylesheet" href="admin.css">
<body rightmargin=0>
<div align=center class=trTitle>Détection de la triche</div>
<br>

<?php
#########################################
# constants
#########################################
$tabEquiv = array();
$tabEquiv[Password][weight]=80000000;
$tabEquiv[IP][weight]=7000000;
$tabEquiv[Email][weight]=600000;
$tabEquiv[PTime][weight]=50000;
$tabEquiv[Browser][weight]=4000;
$tabEquiv[Zip][weight]=300;
$tabEquiv[Gender][weight]=20;
$tabEquiv[Age][weight]=1;

$tabEquiv[Password][operator]="equal";
$tabEquiv[IP][operator]="equal";
$tabEquiv[Browser][operator]="equal";
$tabEquiv[Zip][operator]="equal";
$tabEquiv[Gender][operator]="equal";
$tabEquiv[Age][operator]="equal";

$tabEquiv[PTime][operator]="time_diff";
$tabEquiv[PTime][minDiff]=300;

$tabEquiv[Email][operator]="email";



$NOT_SUSPECT = -1;
$FIELDS_EQUIV = "Password,IP,Browser,Zip,Gender,Age,Players.Time AS PTime,Email";

#########################################
# DEBUG FUNCTIONS - START
#########################################
# affiche le tableau tabOdds
function showTabOdds($tabOdds)
{
	$nbTabOdds = count($tabOdds);
	for($r=0;$r<$nbTabOdds;$r++)
	{
		echo "MId:".$tabOdds[$r][Id];
		echo " OddId:".$tabOdds[$r][OddId];
		echo " susp:".$tabOdds[$r][Suspicion];
		echo "<br>";
	}
}

function test()
{
	global $tabEquiv;
	
	#recup d'un pere et d'un fils
	# 1er method
	$father=db_fetch_array(main_db_query("select * from Members where Id='3'"));
	$son = db_fetch_array(main_db_query("select * from Members where Id='4'"));
	
	echo "1er:".checkFatherToSon($father,$son)."<br>";
	echo "2:".memberEquiv($father,$son,$tabEquiv)."<br>";
}
#########################################
# DEBUG FUNCTIONS - END
#########################################




#########################################
# BACK OFFICE FUNCTIONS - START
#########################################

#########################################
# function qui retourne le "degrée" d'equivalence (suspicion)
# entre deux membres row1 et row2.
# L'equivalence est calculée suivant le tableau tabEquiv (passé en référence)
# qui indique pour chaque champ d'un membre l'operateur de comparaison
# du champs et la pondération du champs.
# Chaque champs de row1 est comparé avec son homologue dans row2 suivant l'operateur défini dans
# tabEquiv pour le champ indiqué. Si la comparaison est vraie, la pondération du champs est ajouté
# à la suspicion. La fonction retourne la suspicion qui est donc une somme de pondérations.
#########################################
function memberEquiv($row1,$row2,&$tabEquiv)
{
	$suspicion=0;
	
	reset($tabEquiv);

	# on parcourt chaque champs défini par tabEquiv
	while(list($field,$properties)=each($tabEquiv))
	{
		$add=false;
		
		# suivant le type d'operateur, on applique la fonction de comparaison adéquate
		switch($properties[operator])
		{
			case "equal":
				$add = ($row1[$field]==$row2[$field]);
				break;
				
			case "time_diff":
				# dans le cas d'une comparaison de date, on "déclenche l'alerte"
				# lorsque le delta de temps entre les deux dates est inférieur à une 
				# valeur définie dans tabEquiv
				$add = (time_diff($row1[$field],$row2[$field])<=$properties[minDiff]);
				break;
			
			case "email":
				# on compare le domaine name des emails
				$t1 = explode("@",$row1[$field]);
				$t2 = explode("@",$row2[$field]);
				$add = ($t1[1]==$t2[1]);
		}
		
		# on ajoute la suspicion (suivant la pondération du champs)
		if ($add)
			$suspicion += $properties[weight];
	}
	return $suspicion;
}

#########################################
# à partir d'un rows de membres, cette fonction retourne
# un tableau contenant les n-upplets suspects.
# Algo :
# On calcule la suspicion de chaque couple du tableau (on a donc une fonction qui parcourt les couples).
# Pour un membre donné, on garde le membre avec lequel il a obtenu la plus haute suspicion.
# le dernier membre obtient toujours -1 car les couples se font de haut (du tableau) en bas, ce
# qui ne veut pas dire qu'il n'est pas couplé of course.
#########################################
function buildCouples($rows)
{
	global $tabEquiv,$NOT_SUSPECT;
	
	# on crée le tableau qui conservera les n-upplets de membre
	$tabOdds=array();
	
	$nbRows = db_num_rows($rows);
	for($r=0;$r<$nbRows;$r++)
	{
		# on positionne le pointeur
		db_data_seek($rows,$r);
		
		# on recupere le premier membre
		$row1 = db_fetch_array($rows);

		# on indique l'Id de l'indice de rang r
		$tabOdds[$r][Id]=$row1[MId];

		# s'il n'a pas encore été couplé, on le présume innocent
		$tabOdds[$r][OddId]=$NOT_SUSPECT;

		for($i=$r+1;$i<$nbRows;$i++)
		{
			# on positionne le pointeur
			db_data_seek($rows,$i);
			
			# recup du row2
			$row2 = db_fetch_array($rows);
			
			# on effectue la comparaison
			$suspicion = memberEquiv($row1,$row2,&$tabEquiv);
			
			# si la suspicion row1/row2 est supérieur à celle d'avant
			# on la remplace
			if ($tabOdds[$r][Suspicion]<$suspicion)
			{
				$tabOdds[$r][OddId]=$row2[MId];
				$tabOdds[$r][Suspicion]=$suspicion;
			}
		}
	}
	return $tabOdds;
}
#########################################
# BACK OFFICE FUNCTIONS - END
#########################################


#########################################
# PRESENTATION FUNCTIONS - START
#########################################
function showTabEquiv(&$tabEquiv)
{
	reset($tabEquiv);
	
	echo "<table border=1>";
	# on parcourt chaque champs défini par tabEquiv
	while(list($field,$properties)=each($tabEquiv))
	{
		echo "<tr>";
		echo "<td>".$field."</td><td align=right>".$properties[weight]."</td>";
		echo "</tr>";
	}
	echo "</table>";
}

function showTitle($table)
{
	$columns = main_db_query("SHOW COLUMNS FROM ".$table);
	
	while($column=db_fetch_array($columns))
		echo "<td>".$column[0]."</td>\n";
}

function showRow($table,$req)
{
	$row = db_fetch_array(main_db_query($req));
	$columns = main_db_query("SHOW COLUMNS FROM ".$table);
	
	while($column=db_fetch_array($columns))
		echo "<td>".$row[$column[0]]."</td>\n";
}

function showMember($memberId,$suspicion=0)
{
	static $nCheckbox;
	
	# permet de connaitre combien de membre ont été affiché
	$nCheckbox++;
	
	# recup du player
	$player = getplayer($memberId);
	
	echo "<tr>";
	
	# affiche la check-box pour séparer le filleul
	echo "<td><input type=checkbox name=check".$nCheckbox." value=".$player[Id]."></td>";
	
	# requete pour afficher le membre
	$req = "SELECT * FROM Members WHERE Id='".$memberId."'";
	$table = "Members";
	showRow($table,$req);
	
	# requete pour afficher le player
	$req = "SELECT * FROM Players WHERE MemberId='".$memberId."'";
	$table = "Players";
	showRow($table,$req);
	
	# affiche la suspicion
	if ($suspicion!=0)
		echo "<td>".$suspicion."</td>";
	else
		echo "<td></td>";
	
	# affiche le score
	echo "<td>".$player[Score]."</td>";
	
	# on va chercher le nbr de fois qu'il a joué
	$row = db_fetch_array(main_db_query("SELECT COUNT(*) AS total FROM Paris WHERE PlayerId='".$player[Id]."'"));
	echo "<td>".$row[total]."</td>";

	# affiche la date du dernier pari effectué
	$row = db_fetch_array(main_db_query("SELECT Date FROM Paris WHERE PlayerId='".$player[Id]."' ORDER BY Date DESC LIMIT 0,1"));
	echo "<td>".$row['Date']."</td>";
	
	echo "</tr>\n";
	
	return $nCheckbox;
}

# show the suspects for on member
function showSuspicion($memberId,$suspicion_limit)
{
	global $FIELDS_EQUIV,$NOT_SUSPECT;
	
	# on verifie la suspicion entre le parrain et chacun de ses filleuls
	# a faire
	
	# on verifie les filleuls entre eux
	# recup du PId du member
	$player = getplayer($memberId);
	
	# ce qu'on prend ici dépend du tabEquiv egalement
	$rows = main_db_query("SELECT ".
		" Members.Id AS MId, Players.Id AS PId, ".
		$FIELDS_EQUIV.
		" FROM Members ".
		" LEFT JOIN Players ON Players.MemberId=Members.Id".
		" WHERE ".
		" FatherPId='".$player[Id]."'");

	$nbFilleuls = db_num_rows($rows);
	$tabOdds = buildCouples($rows);
	
	$nbTabOdds = count($tabOdds);

	# on va traiter le tabOdds en ne gardant que les couples qui sont 
	# au dessus de suspicion_limit
	for($r=0;$r<$nbTabOdds;$r++)
	{
		# verifie que le membre n'a pas déjà été traité
		if ($oddsDone[$tabOdds[$r][Id]]!=1)
		{
			if ($tabOdds[$r][Suspicion]>=$suspicion_limit)
			{
				# on indique que le couple de member a été traité
				$oddsShow[$tabOdds[$r][Id]]=1;
				$oddsShow[$tabOdds[$r][OddId]]=1;
			}
		}
	}

	echo "Player : ".$player[NickName]."<br>";
	
	# on affiche le parrain
	echo "<table border=1 cellpadding=0 cellspacing=0><tr>";
	echo "<td></td>";
	showTitle("Members");
	showTitle("Players");
	echo "<td>susp</td><td>Score</td><td>Joué</td><td>Dernier&nbsp;pari</td>";
	echo "</tr>\n";
	showMember($player[MemberId]);
	
	# affiche les filleuls
	echo "nb de filleuls : ".$nbFilleuls."<br>";

	# affiche la table de résultat en brut
	showTabOdds($tabOdds);

	echo "<table border=1><tr>";
	echo "<td></td>";
	showTitle("Members");
	showTitle("Players");
	echo "<td>susp</td><td>Score</td><td>Joué</td><td>Dernier&nbsp;pari</td>";
	echo "</tr>\n";
	# maintenant on a dans oddsShow les membres à montrer
	# il suffit de les afficher
	for($r=0;$r<$nbTabOdds;$r++)
	{
		if ($oddsShow[$tabOdds[$r][Id]]==1)
			$nCheckBox = showMember($tabOdds[$r][Id],$tabOdds[$r][Suspicion]);
	}
	echo "</table>\n";
	flush();
	
	return $nCheckBox;
}
#########################################
# PRESENTATION FUNCTIONS - END
#########################################


#########################################
# MAIN - START
#########################################
$SUSPICION_LIMIT = (isset($SUSPICION_LIMIT))?$SUSPICION_LIMIT:10000;

# Ecran 1
if ($submitNick=="Valider")
{
	if (!empty($NickName))
	{
		$row=db_fetch_array(main_db_query("SELECT Members.Id AS MId FROM Members LEFT JOIN Players ON Players.MemberId=Members.Id WHERE NickName='".$NickName."'"));
		$memberId = $row[MId];
	}
	# affichage de la table de pondération
	showTabEquiv(&$tabEquiv);
	$nCheckBox = showSuspicion($memberId,$SUSPICION_LIMIT);
}
else if ($submitFirst=="Valider")
{
	$nPlayers = main_db_query("SELECT MemberId FROM Players ORDER BY Score DESC, Time ASC LIMIT 0, ".$nbMembers);
	
	# affichage de la table de pondération
	showTabEquiv(&$tabEquiv);
	while($aPlayer = db_fetch_array($nPlayers))
	{
		echo "<hr>";
		$nCheckBox = showSuspicion($aPlayer[MemberId],$SUSPICION_LIMIT);
	}
}
# Ecran 2 (si séparation)
else if ($detach=="Detacher")
{
	$i=0;
	for($r=1;$r<=$nCheckBox;$r++)
	{
		$var_temp = "check".$r;
		if (isset($$var_temp))
		{
			echo "<input type=hidden name=check".$i." value=".$$var_temp.">";
			list($father,$son) = getCouple($$var_temp);
			echo $father."/".$son;
			echo "<br>";
			$i++;
		}
	}
?>
<input type=hidden name=nbToDetach value="<?php echo $i ?>">
Confirmer la séparation des couples ci-dessus ?
<br>
<input type=submit name=detach2 value="Confirmer">
</form>
<?php
}
# Ecran 3 (si séparation)
else if ($detach2=="Confirmer")
{
	for ($r=0;$r<$nbToDetach;$r++)
	{
		$var_temp = "check".$r;
		echo "<br><br>&gt; separation de : ";
		list($father,$son) = getCouple($$var_temp);
		echo $father."/".$son;
		echo "<br>";
		detachSon($$var_temp);
	}
}
#########################################
# MAIN - END
#########################################
?>
	<input type=hidden name=nCheckBox value="<?php echo $nCheckBox ?>">
	Palier de suspicion : <input type=text name=SUSPICION_LIMIT value="<?php echo $SUSPICION_LIMIT ?>">
	<br><br>
	Pseudo : <input type=text name=NickName value="<?php echo $NickName ?>">
	<input type=submit name=submitNick value="Valider">
	<br>
	ou
	<br>
	les <input type=text name=nbMembers value="<?php echo $nbMembers ?>"> premiers
	<input type=submit name=submitFirst value="Valider">
	<br><br>
	Détacher les joueurs cochés
	<input type=submit name=detach value="Detacher">
</form>
