Jump to content

[PHP] Live kill feed


Defent

Recommended Posts

 

Setup a shared drive on the webserver where you would like the file to stay.

 

Create a new limited access user account that can be used to login to that share.  Make sure the account is not having any access to the game server.

 

Mount the shared drive on you game server (using the restricted access account). 

 

Setup a batchfile to run robocopy to sync the gameserver rpt with the remote share location (push from game server to webserver for security reasons).

 

Use Windows task schedular to run the batch file automatically every XXX minutes.

 

Any way to go more indepth with how to do this? My website is CentOS 6.5 x64 so not sure if I can make a shared drive.

Link to comment
Share on other sites

  • 4 weeks later...
  • 3 weeks later...
  • 2 months later...

A while ago I asked Defent's permission to make a completely new version of his PHP killfeed script. He gave me the permission. I almost completed it but other important things got in the way and I haven't been able to come back to the script ever since. It is working perfectly as it should but it's lacking some features I was planning to make. So anyway, I'm releasing it pre-maturely in this topic instead of making it a new release (since it's not as complete as I would like it to be).

 

Download files here!

 

Installation is quite simple. Open up killfeed.php and at the top of the file there are configuration variables that you need to change. After you're done, save the file and place all files anywhere on your web server and access killfeed.php from your browser. Note! There is only 1 difficulty with this though. The PHP files and the RPT log file must be in the same server. So for people with rented hosting this might be difficult. 

 

You can see the script running here: http://dayz.kriba.ee/ (scroll down, under shoutbox)

For this particular example I have Overpoch and the PHP files running on the same server but the website (dayz.kriba.ee) is on a different server. So I installed WAMP on my Overpoch server and made killfeed.php publicly available via http. Then I added a simple iframe script on my website's server like so: 

<iframe src="http://your_servers_ip/killfeed.php" style="border: 0px" width="940px" height="150"></iframe>

So what is this script? It's just more-complex and much more easy to customize. It has more features and is more bulletproof. With Defent's original version I found that if you have a killfeed message like so:

 

[time] Player1 killed Player2 with weapon DMR from distance 100 meters.

 

And if, for example, Player2 would change his name to something like "with weapon DMR" all sorts of crap would go down. This is fixed now as long as the server doesn't allow quotation marks in player's name.

Some other features include:

  • Fully customizable killfeed string: [%time] <b>%victim</b> was killed by <b>%killer</b> with weapon <b>%weapon</b> from distance <b>%distance</b> meters.
  • Limit the number of lines displayed
  • Hide/show suicides
  • Round up the distance number, so you don't get 100.3423432 meters
  • Switch time between AM/PM and 24-hour format
  • You can remove "seconds" from time
  • And last but not least - replaces all class names with real names (e.g Mk_48_DZ = Mk 48 mod 0) and yes, it does include Overwatch weapons

 

One thing I should note though. The class name list doesn't have ALL weapons. There are probably some still missing. Some might not be 100% accurate as well. For example "M240_Scoped_DZ" might actually not be "M240 Scoped", instead just "M240". I grabbed as many weapons class name lists from the interwebs as I could.

 

Adding new class names for replacement is very simple. Open up killfeed_weapon_classnames.php and killfeed_weapon_cleannames.php and just add a new variable at the bottom of the file (before PHP's closing brackets ?> of course). But make sure the line numbers match up from class names file and clean names file. Otherwise it replaces the weapon's name with something else. Also remember not to add any quotation marks (") in the clean names.

 

killfeednames.jpg

 

(Line numbers must match)

 

 

Originally I had lots of plans for this script like replacing the gun names with actual images, showing how many bullets it took to kill the victim, generating statistics on who kills who the most, etc etc. I also wanted to include theballin7's DLL for this script instead of using the RPT log file but he never responed to my letters so I went with the log file.

 

 

Edit// For all of you code-wizards out there who just want to see the code, here's the main file killfeed.php:

<?php
// Configuration
// Note! Do not use actual quotation marks (") when writing values "true" or "false"
// This is correct: $conf_time_pm = true;
// This is not correct: $conf_time_pm = "true";
$conf_rpt_location = "C:\Program Files (x86)\Steam\SteamApps\common\Arma 2 Operation Arrowhead\instance_11_Chernarus\arma2oaserver.RPT"; // Server's RPT log file location. Usually in the folder I have as an example
$conf_max_lines = 30;					// Maximum amount of feed displayed. "False" - limitless
$conf_distance_round = 2;				// Number of digits after distance's decimal point (e.g. $conf_distance_round = 2; would make the distance number look like: 530.62 meters)
$conf_time_pm = false;					// Timestamp format. "True" = AM/PM format. "False" = 24-hour format
$conf_time_seconds = true;				// Keep seconds in timestamp? "True" keeps seconds in timestamp. "False" = removes seconds from timestamp
$conf_skip_suicides = true;				// Skip suicides? "True" = skips all suicides. "False" = doesn't skip suicides
$conf_replace_classnames = true;		// Replace weapon class names with normal names? "True" = replaces class names. "False" = doesn't replace class names

$conf_str_unknown = "unknown"; // Word for missing data. Ex: "Rocu was killed by unknown."

$conf_str_kill = '[%time] <b>%victim</b> was killed by <b>%killer</b> with weapon <b>%weapon</b> from distance <b>%distance</b> meters.'; // Fully customizable kill string, edit/leave parts out if you wish
		// %time 		- time, when the event happened
		// %victim		- person, who got killed
		// %killer 		- person, who killed the victim
		// %weapon	- weapon, that the killer used
		// %distance	- distance between killer and victim (meters)
		
$conf_str_suicide = '[%time] %victim killed himself.'; // Fully customizable suicide string
		// %time 		- time, when the event happened
		// %victim		- person, who died
		
// Configuration end, do not edit anything beyond this point
?>
<html>
<head>
<title>DayZ Killfeed</title>
<style>
* {
	font-family: Calibri;
	font-size: 12px;
}
</style>
</head>
<body>

<a href="javascript:location.reload(true)">Refresh killfeed</a><br />

<?php
if (!file_exists($conf_rpt_location)) {
	exit("ERROR: Invalid RPT log file (doesn't exist)");
}

$input = array_reverse(file($conf_rpt_location),1);

function sprintf2($str='', $vars=array(), $char='%')
{
	if (!$str) return '';
	if (count($vars) > 0)
	{
		foreach ($vars as $k => $v)
		{
			$str = str_replace($char . $k, $v, $str);
		}
	}
	return $str;
}

function cleanData($arr=array(), $data_type='suicide', $unknown_msg) {
	foreach ($arr as $key => $value) {
		if (is_int($key)) {
			unset($arr[$key]); continue;
		}
		$arr[$key] = str_replace('"','',$value);
	}
	
	$keycount=0;
	$loopcount=0;
	
	if ($data_type == 'suicide') {
		$data_keys = array('time','victim');
	} elseif ($data_type == 'kill') {
		$data_keys = array('time','victim','killer','weapon','distance');
	} else {
		return $arr;
	}
	
	foreach ($arr as $key => $value) {
		$loopcount++;
		if (in_array($key, $data_keys)) {
			foreach ($data_keys as $key_dk => $value_dk) {
				if ($value_dk == $key) { 
					unset($data_keys[$key_dk]); 
					$keycount++; 
					// If empty value, insert unknown string
					if (empty(trim($value))) { $arr[$key] = $unknown_msg; }
					break;
				}
			}
		}
		if ($keycount < 5 && $loopcount >= count($arr)) {
			foreach ($data_keys as $value_dk) {
				// If missing key, insert key with unknown key as value
				$arr[$value_dk] = $unknown_msg;
			}
		}
	}
	
	return $arr;
}



$i=0;
foreach ($input as $line)
{
	if(strpos($line, "PKILL:") != false)
	{
		$line = str_replace(' ', '" "', trim($line));
		// Fool-proof quote system to prevent abusers from trying to exploit the string-processing regular expression
		
		if (preg_match('/(?P<time>.*)" ""PKILL:" "(?P<victim>.*)" "killed" "(him|her)self"/', $line, $data)) 
		{
			// Player killed by zombies/suicide
			if ($conf_skip_suicides === true) { $is_suicide = true; continue; }
			
			$line_type = 'suicide';
			$data = cleanData($data,$line_type,$conf_str_unknown);
			if (count($data) < 2) {continue;}
			
			$line_string = $conf_str_suicide;
			$line_varlist = array(
				'time' => $data['time'],
				'victim' => $data['victim']
			);
		}
		elseif (preg_match('/(?P<time>.*)" ""PKILL:" "(?P<victim>.*)" "was" "killed" "by" "(?P<killer>.*)" "with" "weapon" "(?P<weapon>.*)" "from" "(?P<distance>.*)m"/', $line, $data)) 
		{
			// Player killed by another player
			
			$line_type = 'kill';
			$data = cleanData($data,$line_type,$conf_str_unknown);
			if (count($data) < 5) {continue;}
			
			$line_string = $conf_str_kill;
			$line_varlist = array(
				'time' => $data['time'],
				'victim' => $data['victim'],
				'killer' => $data['killer'],
				'weapon' => $data['weapon'],
				'distance' => $data['distance']
			);
		} else {
			continue;
		}
		
		// Round to 1 decimal point
		$line_varlist['distance'] = round($line_varlist['distance'], $conf_distance_round);
		
		// Add the missing 0 which the log doesn't seem to do
		$line_varlist['time'] = str_pad($line_varlist['time'], 8, '0', STR_PAD_LEFT);
		
		if ($conf_time_pm === true) {
			$line_varlist['time'] = date("h:i:s a", strtotime($line_varlist['time']));
		}
		
		if ($conf_time_seconds === false) {
			$line_varlist['time'] = substr_replace($line_varlist['time'], '', 5, 3);
		}
		
		if ($conf_replace_classnames === true && $line_type == 'kill') {
			include("killfeed_weapon_classnames.php");
			include("killfeed_weapon_cleannames.php");
			$swap_key = array_search($line_varlist['weapon'], $wcn);
			if($swap_key != false) { $line_varlist['weapon'] = $wn[$swap_key]; }
		}
		
		echo sprintf2($line_string, $line_varlist);
		echo "<br />";
		
		$i++;
		if ($conf_max_lines != false) {
			if (is_numeric($conf_max_lines) && $i >= $conf_max_lines) {
				break;
			}
		}
	}
}

if ($i < 1) {
	echo 'No killfeed available yet';
}
?>

<!-- Y u eyeballin my source? -->
<!-- From Rocu with love :3 -->

</body>
</html> 

Edited by Rocu
Link to comment
Share on other sites

  • 1 month later...
  • 2 months later...

 

My code, all kills.

<?php
$file = 'C:\dayz\server\instance_11_Chernarus\arma2oaserver.RPT';
$searchfor = 'PKILL:';

    header('Content-Type: text/plain');
    $contents = file_get_contents($file);

    $pattern = preg_quote($searchfor, '/');

    $pattern = "/^.*$pattern.*$/m";

  if(preg_match_all($pattern, $contents, $matches)){
     echo "Kill list: 
 ";
     echo implode(" ", $matches[0]);
     }
  else {
     echo "Not Kills!";
       }

 ?>

 

How do I make this print in white text?

This is the reason why I ask:http://ndz.no/index.php/killboard-showall

Link to comment
Share on other sites

How do I make this print in white text?

This is the reason why I ask:http://ndz.no/index.php/killboard-showall

 

Got a new code now

<?php
$file = 'C:\Epoch server\instance_11_Chernarus\arma2oaserver.RPT';
$searchfor = 'PKILL:';

    header('Content-Type: text/html');
    $contents = file_get_contents($file);

    $pattern = preg_quote($searchfor, '/');

    $pattern = "/^.*$pattern.*$/m";

  if(preg_match_all($pattern, $contents, $matches)){
     echo "<div style ='font:11px/21px Arial,tahoma,sans-serif;color:#ffffff'>Killboard: <br>";
     echo '', implode(" <br>", $matches[0]);
     }
  else {
     echo "Not Kills!";
       }

 ?>

Green = changes...

 

I got no </div> wherever I place it - it fails, but now it works... are there any problems with not closing the div?

Link to comment
Share on other sites

  • 3 years later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Advertisement
  • Discord

×
×
  • Create New...