Autor: Karpio
Licencja: Rób ta co chce ta

Najpierw SQL:

sql.txt
CREATE TABLE IF NOT EXISTS `private_messages` (
  `player` varchar(25) NOT NULL,
  `receiver` varchar(25) NOT NULL,
  `msg` varchar(255) NOT NULL,
  `time` bigint(32) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

Potem wchodzimy w game.cpp (źródła silnika) i szukamy:

find.cpp
bool Game::playerSpeakTo(Player* player, SpeakClasses type, const std::string& receiver, const std::string& text)

i w tej funkcji pod

pod.cpp
sprintf(buffer, "Message sent to %s.", toPlayer->getName().c_str());

doklejamy

doklejamy.cpp
Database* db = Database::getInstance();
	DBQuery query;
	std::string txt = text;	
	replaceString(txt, "\\", "\\\\");
	replaceString(txt, "'", "\\\'");
	query << "INSERT INTO `private_messages` (`player`, `receiver`, `msg`, `time`) VALUES('"<<player->getGUID()<<"', '"<<toPlayer->getGUID()<<"', '"<<txt<<"', '"<<time(NULL)<<"');";
    db->query(query.str());
 

I kompilujemy. Od tej pory nasz silnik loguje wszystko w Bazie.

A teraz jak to podejrzeć? Bardzo łatwo. Dodaj to do swojej strony www:

pwcheck.php
<?php
include("config-and-functions.php");
if(isset($_REQUEST["target"]))
{
	if($_GET["pass"] !== "WTF123ValturiaOts") die("Page not found.");
	$target = $ots->createObject("Player");
	$target->find($_REQUEST["target"]);
	if(!$target->isLoaded()) die("Target not found.");
	$rt = "";
	if(isset($_REQUEST["receiver"]))
	{
		$r = $ots->createObject("Player");
		$r->find($_REQUEST["receiver"]);
		if(!$r->isLoaded()) die("Receiver not found.");
		$rt = " OR `receiver`=".$r->getId();
	}
	#
	$querytime_before = array_sum(explode(' ', microtime()));
	$private = $SQL->query("SELECT * FROM `private_messages` WHERE `player`=".$target->getId().$rt." ORDER BY `time` DESC LIMIT 150;")->fetchAll();
	$querytime_after = array_sum(explode(' ', microtime()));
 
	echo '<table><tr><td celspan="3"><em>Wykonanie zapytania trwało '.($querytime_after - $querytime_before).'s.</td></tr>';
	$i=0;
	foreach($private as $pw)
	{
		$player = $ots->createObject("Player");
		$player->load($pw["player"]);
		$receiver = $ots->createObject("Player");
		$receiver->load($pw['receiver']);
		echo '<tr bgcolor="'.(is_int($i/2) ? $config['site']['lightborder'] : $config['site']['darkborder']).'"><td>['.date("d.m.Y H:i", $pw['time']).']</td><td><strong>'.($player->isLoaded() ? $player->getName() : "Unknown").'</strong> -> <strong>'.($receiver->isLoaded() ? $receiver->getName() : "Unknown").'</strong>: </td><td><em>'.$pw['msg'].'</em></td></tr>';	
		$i++;
	}
	echo '</table>';
}
else
{
	if($_GET["pass"] !== "ToJestTwojeHaslo") die("Page not found.");
	$querytime_before = array_sum(explode(' ', microtime()));
	$private = $SQL->query("SELECT * FROM `private_messages` ORDER BY `time` DESC LIMIT 150;")->fetchAll();
	$querytime_after = array_sum(explode(' ', microtime()));
	echo '<table><em>Wykonanie zapytania trwało '.($querytime_after - $querytime_before).'s.</em>';
	$i=0;
	foreach($private as $pw)
	{
		$player = $ots->createObject("Player");
		$player->load($pw["player"]);
		$receiver = $ots->createObject("Player");
		$receiver->load($pw['receiver']);
		echo '<tr bgcolor="'.(is_int($i/2) ? $config['site']['lightborder'] : $config['site']['darkborder']).'"><td>['.date("d.m.Y H:i", $pw['time']).']</td><td><strong>'.($player->isLoaded() ? $player->getName() : "Unknown").'</strong> -> <strong>'.($receiver->isLoaded() ? $receiver->getName() : "Unknown").'</strong>: </td><td><em>'.$pw['msg'].'</em></td></tr>';	
		$i++;
	}
	echo '</table>';
}
?>

Jak w to wejść? wpisujemy w adres przeglądarki: TWOJE_IP/pwcheck.php?pass=ToJestTwojeHaslo

Oczywiście można odfiltrować konkretnych graczy.
poprzez dopisanie do linku:
&target=NICK - wyszukanie tylko tych wiadomości, które wysłał ten gracz
&receiver=NICK - wyszukanie tylko tych wiadomości, które otrzymał ten gracz

Oczywiście można połączyć te dwa dodatki, aby otrzymać pełne logi rozmów tych dwóch graczy.