*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
*/
if(!extension_loaded('gtk'))
{
dl('php_gtk.'.PHP_SHLIB_SUFFIX);
}
define('DDID', 0);
define('DDNAME', 1);
define('DDDEALT', 2);
define('DDTAKEN', 3);
$wcolor = &new GdkColor(0xee00, 0xee00, 0xff00);
$bcolor = &new GdkColor(0xe000, 0xe000, 0xf000);
$Bcolor = &new GdkColor(0xd000, 0xd000, 0xe000);
$window = &new GtkWindow;
$window->connect('delete-event', 'exit_dumper');
$window->set_title('Auno\'s Damage Dumper $Revision: 1.9 $');
$window->set_border_width(0);
$wstyle = &$window->get_style();
$wstyle->bg[GTK_STATE_NORMAL] = $wcolor;
$vbox = &new GtkVBox();
$window->add($vbox);
$vbox->show();
$hbox = &new GtkHBox(false, 1);
$hbox->set_border_width(5);
$vbox->pack_start($hbox, false, false);
$hbox->show();
$flabel = &new GtkLabel('No log file open');
$hbox->pack_start($flabel);
$flabel->show();
$hbox = &new GtkHBox(false, 3);
$hbox->set_border_width(5);
$vbox->pack_start($hbox, false, false);
$hbox->show();
$btnreset = &new GtkButton('Reset');
$btnreset->connect_object('clicked', 'initialize_dumper');
$bstyle = &$btnreset->get_style();
$bstyle->bg[GTK_STATE_NORMAL] = $bcolor;
$bstyle->bg[GTK_STATE_PRELIGHT] = $Bcolor;
$hbox->pack_start($btnreset);
$btnreset->show();
$btnpause = &new GtkButton('Pause');
$btnpause->connect_object('clicked', 'pause_cont');
$hbox->pack_start($btnpause);
$btnpause->show();
$btnselect = &new GtkButton('Select Char');
$btnselect->connect('clicked', 'make_log');
$hbox->pack_start($btnselect);
$btnselect->show();
$scrolled_win = &new GtkScrolledWindow();
$scrolled_win->set_border_width(2);
$scrolled_win->set_policy(GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
$vbox->pack_start($scrolled_win);
$scrolled_win->show();
$titles = array("#", "Name", "Damage done", "Damage taken");
$clist = &new GtkCList(sizeof($titles), $titles);
$clist->connect('click_column', 'clist_click_column');
$clist->connect('button-press-event', 'clist_button_press');
$scrolled_win->add($clist);
$clist->show();
$clist->set_row_height(18);
$clist->set_selection_mode(GTK_SELECTION_EXTENDED);
$clist->set_column_auto_resize(DDID, true);
$clist->set_column_auto_resize(DDNAME, true);
$clist->set_column_auto_resize(DDDEALT, true);
$clist->set_column_auto_resize(DDTAKEN, true);
$clist->set_column_justification(DDID, GTK_JUSTIFY_RIGHT);
$clist->set_column_justification(DDNAME, GTK_JUSTIFY_LEFT);
$clist->set_column_justification(DDDEALT, GTK_JUSTIFY_RIGHT);
$clist->set_column_justification(DDTAKEN, GTK_JUSTIFY_RIGHT);
$hbox = &new GtkHBox(false, 1);
$hbox->set_border_width(5);
$vbox->pack_start($hbox, false, false);
$hbox->show();
$slabel = &new GtkLabel('');
$hbox->pack_start($slabel);
$slabel->show();
$window->show();
$savefile = dirname(__FILE__)."\\damagedumper.cfg";
$savevars = array('fn');
restore_config();
initialize_dumper();
Gtk::timeout_add(1000, "read_log");
Gtk::timeout_add(60*1000, "change_minute");
Gtk::main();
function restore_config()
{
global $savefile;
if(!file_exists($savefile))
return;
$cfg = unserialize(file_get_contents($savefile));
if(!is_array($cfg))
return;
foreach($cfg as $key=>$val)
{
$GLOBALS[$key] = $val;
}
}
function save_config()
{
global $savevars, $savefile;
$cfg = array();
foreach($savevars as $var)
{
$cfg[$var] = $GLOBALS[$var];
}
$fd = fopen($savefile, "w");
fwrite($fd, serialize($cfg));
fclose($fd);
}
function pause_cont()
{
global $paused, $btnpause;
$childs = $btnpause->children();
if($paused === true)
{
$childs[0]->set_text("Pause");
$paused = false;
}
else
{
$childs[0]->set_text("Continue");
$paused = true;
}
}
function change_minute()
{
global $exp;
$exp['rate'] = array_sum($exp['hourly']);
$exp['minute'] = ($exp['minute']+1)%60;
$exp['hourly'][$exp['minute']] = 0;
update_slabel();
return true;
}
function read_log()
{
global $fd, $paused, $clist, $exp;
if($paused || !$fd || !is_resource($fd))
return TRUE;
$frozen = false;
for(;;)
{
$line = fgets($fd, 0x200);
if(empty($line))
{
fseek($fd, 0, SEEK_CUR); // clear eof
break;
}
$line = substr(strstr($line, "]"), 1);
$ret = 1 * !!preg_match("#^(.*?) hit (.*?) for ([0-9]+) points of (.*?) damage#", $line, $reg);
if($ret == 0)
$ret = 2 * !!preg_match("#^(.*?) w[ea][rs]e? attacked with .*? from (.*?) for ([0-9]+) points of (.*?) damage#", $line, $reg);
if($ret == 0)
$ret = 3 * !!preg_match("#^(.*?) ([a-z]+ shield) hit (.*?) for ([0-9]+) points#", $line, $reg);
if($ret != 0)
{
if($ret < 3)
{
$dealer = $reg[$ret];
$taker = $reg[3-$ret];
$amount = (int)$reg[3];
$type = $reg[4];
}
else if($ret == 3)
{
$dealer = $reg[1];
$taker = $reg[3];
$amount = (int)$reg[4];
$type = $reg[2];
if($dealer === 'Your')
$dealer = 'You';
else
$dealer = substr($dealer, 0, -2);
}
if($taker === "you")
$taker = "You";
else if(($x = strpos($taker, " with ")) !== false)
$taker = substr($taker, 0, $x);
// echo "Damage($ret) $amount : $dealer -> $taker\n";
if($frozen === false)
{
$frozen = true;
$clist->freeze();
}
update_damage($dealer, true, $amount, $type);
update_damage($taker, false, $amount, $type);
}
else if(preg_match('#^You gained ([0-9]+) points of Shadowknowledg#', $line, $reg))
{
$sk = (int)$reg[1];
$exp['total'] += $sk;
$exp['hourly'][$exp['minute']] += $sk;
update_slabel();
}
}
if($frozen === true)
{
$clist->thaw();
}
return TRUE;
}
function update_damage($who, $type, $amount, $dmgtype)
{
global $damage, $clist, $rows, $sort_col;
if(!isset($damage[$who]))
{
$damage[$who] = array('row' => (int)($rows++),
'dealt' => $type ? $amount : 0,
'taken' => $type ? 0 : $amount,
'dealt-type' => array(),
'taken-type' => array());
$clist->append(array($rows, $who, $damage[$who]['dealt'], $damage[$who]['taken']));
}
else
{
$damage[$who][$type ? 'dealt' : 'taken'] += $amount;
$clist->set_text($damage[$who]['row'], $type ? DDDEALT : DDTAKEN,
$damage[$who][$type ? 'dealt' : 'taken']);
}
$damage[$who][$type ? 'dealt-type' : 'taken-type'][$dmgtype] += $amount;
if($sort_col == ($type ? DDDEALT : DDTAKEN))
{
$scname = $type ? 'dealt' : 'taken';
$row = $damage[$who]['row'];
while($row > 0 && (int)$clist->get_text($row-1, $sort_col) < $damage[$who][$scname])
{
$clist->set_text($row-1, DDID, $row+1);
$clist->set_text($row, DDID, $row);
$damage[$clist->get_text($row-1, DDNAME)]['row'] ++;
$clist->swap_rows($row, $row-1);
$row--;
}
$damage[$who]['row'] = $row;
}
}
function update_slabel()
{
global $slabel, $exp;
$slabel->set_text("SK gained: ".$exp['total']." / During last hour: ".$exp["rate"]);
}
function initialize_dumper()
{
global $clist, $damage, $rows, $paused, $fn, $fd, $flabel, $sort_col, $exp;
$clist->clear();
$damage = array();
$rows = 0;
$paused = false;
$sort_col = DDDEALT;
$exp = array('total' => 0, 'minute' => 0, 'hourly' => array(), 'rate' => 0);
update_slabel();
if($fd)
{
@fclose($fd);
$fd = NULL;
}
if(empty($fn))
return;
clearstatcache();
if(is_file($fn) && is_readable($fn))
$fd = @fopen($fn, "r");
if($fd && is_resource($fd))
{
fseek($fd, 0, SEEK_END);
$dfn = str_replace("\\Chat", "\n\\Chat", $fn);
$flabel->set_text($dfn);
save_config();
}
else
{
$fd = NULL;
$fn = NULL;
}
}
function clist_button_press($clist, $event)
{
global $damage;
if($event->button != 3)
return;
list($row, $col) = $clist->get_selection_info($event->x, $event->y);
$clist->unselect_all();
$clist->select_row($row, $col);
$who = $clist->get_text($row, DDNAME);
$menu = &new GtkMenu();
foreach(array('dealt-type' => 'Damage Dealt', 'taken-type' => 'Damage Taken') as $key => $val)
{
if(sizeof($damage[$who][$key]))
{
$item = &new GtkMenuItem("-- $val --");
$menu->append($item);
$item->show();
arsort($damage[$who][$key]);
foreach($damage[$who][$key] as $type => $amount)
{
$item = &new GtkMenuItem(ucfirst($type)." : ".$amount);
$menu->append($item);
$item->show();
}
}
}
$menu->popup(null, null, null, $event->button, $event->time);
}
function clist_click_column($clist, $column)
{
global $damage, $rows, $sort_col;
$sort_col = $column == DDID ? DDDEALT : $column;
$sort = array();
foreach($damage as $key=>$val)
$sort[$key] = $column == DDNAME ? $key : $val[($sort_col == DDDEALT) ? 'dealt' : 'taken'];
if($sort_col != DDNAME)
arsort($sort);
else
asort($sort);
$rows = 0;
$clist->freeze();
foreach(array_keys($sort) as $key)
{
$clist->set_text($rows, DDID, $rows+1);
$clist->set_text($rows, DDNAME, $key);
$clist->set_text($rows, DDDEALT, $damage[$key]['dealt']);
$clist->set_text($rows, DDTAKEN, $damage[$key]['taken']);
$damage[$key]['row'] = $rows ++;
}
$clist->thaw();
}
function open_log_cb($ret)
{
global $fn;
$fn = $ret;
initialize_dumper();
return true;
}
function open_log()
{
global $filelist_cb;
$filelist_cb = 'open_log_cb';
filelist_select();
}
function make_log()
{
global $filelist_cb;
$filelist_cb = 'create_damage_window';
filelist_select();
}
function filelist_ok($button, $fs)
{
global $filelist_cb;
$fn = $fs->get_filename();
$filelist_cb($fn);
return true;
}
function filelist_cancel()
{
return true;
}
function filelist_select()
{
$fs = &new GtkFileSelection('File Selection');
$ok_button = $fs->ok_button;
$ok_button->connect('clicked', 'filelist_ok', $fs);
$ok_button->connect_object('clicked', array($fs, 'destroy'));
$cancel_button = $fs->cancel_button;
$cancel_button->connect('clicked', 'filelist_cancel');
$cancel_button->connect_object('clicked', array($fs, 'destroy'));
$fs->show();
}
function exit_dumper()
{
exit;
}
function create_damage_window($dir)
{
$files = array("Log.txt" => "", "InputHistory.xml" => "\n");
$files["Config.xml"] = <<
ENDCONFIG;
clearstatcache();
if(!ereg('^.*Char[0-9]+', $dir, $reg))
return false;
$dir = $reg[0]."\\Chat\\Windows\\WindowDD";
if(!is_dir($dir))
mkdir($dir);
foreach($files as $fn => $contents)
{
$file = $dir . "\\" . $fn;
$fd = @fopen($file, "w");
if(!$fd || !is_resource($fd))
return false;
fwrite($fd, $contents);
fclose($fd);
}
$GLOBALS['fn'] = $dir . "\\log.txt";
initialize_dumper();
return true;
}
?>