Mineplex2018-withcommit/Plugins/Mineplex.ReportServer/web/view.php

546 lines
16 KiB
PHP
Raw Normal View History

<?php
require_once('snapshot.php');
require_once('report.php');
require_once('message.php');
require_once('player.php');
2015-12-16 01:22:55 +01:00
const dataDir = 'data/';
2016-02-25 19:18:35 +01:00
const messagesPerPage = 5;
// In Java this is "DateTimeFormatter.ISO_LOCAL_DATE_TIME"
const jsonDateTimeFormat = 'Y-m-d\TH:i:s';
/** @var mysqli[] $connections */
$connections = array(); // String index = Connection name
/** PARSE DB CONNECTIONS */
$dbConfigFile = new SplFileObject('database-config.dat');
if ($dbConfigFile->isFile())
{
while (!$dbConfigFile->eof())
{
$line = trim($dbConfigFile->fgets());
if ($line) // check not empty line
{
$parts = explode(' ', $line);
$fullUrl = $parts[1];
$urlParts = explode('/', $fullUrl);
$host = $urlParts[0];
$database = $urlParts[1];
$name = $parts[0];
$username = $parts[2];
$password = $parts[3];
$connection = new mysqli($host, $username, $password, $database);
if ($connection->connect_error) {
die("Connection \"$name\" failed: $connection->connect_error");
}
$connections[$name] = $connection;
}
}
}
else
{
die('database-config.dat does not exist or is not a file.');
}
/**
* @param String $name
* @return mysqli
*/
function getConnection($name)
{
global $connections;
return $connections[$name];
}
/**
* @param String $filename
* @return array JSON data array.
*/
function toDataArray($filename)
{
return json_decode(file_get_contents($filename), true);
}
/**
* @param String $identifier
* @param array $snapshotData Snapshot data array.
* @return Snapshot
*/
function toSnapshot($identifier, $snapshotData)
{
$timezone = new DateTimeZone($snapshotData["timezone"]);
$players = toPlayers($snapshotData['usernames']);
$messages = toMessages($players, $snapshotData['snapshots'], $timezone);
$generated = parseDateTime($snapshotData["generated"], $timezone);
return new Snapshot($identifier, $messages, $players, $generated);
}
/**
* @param array $reportData
* @param Player[] $players
* @return Report
*/
function toReport($reportData, $players)
{
$id = $reportData["id"];
$serverName = $reportData["serverName"];
$handler = array_key_exists("handler", $reportData) ? getPlayer($players, $reportData["handler"]) : null;
$suspect = getPlayer($players, $reportData["suspect"]);
$reporters = toReporters($players, $reportData["reporters"]);
return new Report($id, $serverName, $handler, $suspect, $reporters);
}
/**
* @param Player[] $players
* @param array $messagesData Messages data array.
* @param DateTimeZone $timezone
* @return Message[]
*/
function toMessages($players, $messagesData, $timezone)
{
$messages = array();
for ($i = 0; $i < count($messagesData); $i++)
{
$messages[$i] = getMessage($players, $messagesData[$i], $timezone);
}
return $messages;
}
/**
* @param Player[] $players
* @param array $messageData Message data array.
* @param DateTimeZone $timezone
* @return Message
*/
function getMessage($players, $messageData, $timezone)
{
$sender = getPlayer($players, $messageData['sender']);
$recipients = getPlayersFromUUIDs($players, $messageData['recipients']);
$dateTime = parseDateTime($messageData['time'], $timezone);
2015-12-16 01:22:55 +01:00
$type = Message::getTypeFromString($messageData['type']);
$message = $messageData['message'];
return new Message($sender, $recipients, $dateTime, $type, $message);
}
/**
* @param Player[] $players
* @param String[] $uuidArray the UUIDs of the players to fetch
* @return Player[]
*/
function getPlayersFromUUIDs($players, $uuidArray)
{
$matchedPlayers = array();
for ($i = 0; $i < count($uuidArray); $i++)
{
$matchedPlayers[$i] = getPlayer($players, $uuidArray[$i]);
}
return $matchedPlayers;
}
/**
* @param Player[] $playersArray
* @return Player[]
*/
function toPlayers($playersArray) // String UUID as Key
{
$players = array();
foreach ($playersArray as $uuid => $username)
{
$connection = getConnection("ACCOUNT");
$statement = $connection->prepare("SELECT `rank` FROM `accounts` WHERE `uuid` = ?;");
$statement->bind_param('s', $uuid);
$statement->execute();
$statement->bind_result($rank);
$statement->fetch();
$statement->close();
$players[$uuid] = new Player($uuid, $username, $rank);
}
return $players;
}
/**
* @param $playersArray
* @param $reportersArray
* @return SplObjectStorage
*/
function toReporters($playersArray, $reportersArray)
{
$reporters = new SplObjectStorage();
foreach ($reportersArray as $reporterUUID => $reason)
{
$reporters[getPlayer($playersArray, $reporterUUID)] = $reason;
}
return $reporters;
}
/**
* @param Player[] $players
* @param String $uuid
* @return Player
*/
function getPlayer($players, $uuid)
{
$player = $players[$uuid];
if ($player != null)
{
return $player;
}
else
{
throw new RuntimeException('Player for UUID not found.');
}
}
/**
* @param String $dateTime
* @param DateTimeZone $timezone
* @return DateTime
*/
function parseDateTime($dateTime, $timezone)
{
return DateTime::createFromFormat(jsonDateTimeFormat, $dateTime, $timezone);
}
/**
* Converts an interval to minutes, days or months, depending on the size.
*
* @param DateInterval $interval
* @return string
*/
function approximateHumanInterval($interval)
{
if ($interval->m > 0)
{
2016-01-30 00:12:50 +01:00
$humanString = $interval->m . ' month' . ($interval->m != 0 ? 's' : '');
}
else if ($interval->d > 0)
{
2016-01-30 00:12:50 +01:00
$humanString = $interval->d . ' day' . ($interval->d != 0 ? 's' : '');
}
else if ($interval->h > 0)
{
2016-01-30 00:12:50 +01:00
$humanString = $interval->h . ' hour' . ($interval->h != 0 ? 's' : '');
}
else
{
2016-01-30 00:12:50 +01:00
$humanString = $interval->i . ' minute' . ($interval->i != 0 ? 's' : '');
}
2016-01-30 00:12:50 +01:00
return $humanString;
}
/**
* @param int $page
* @return string
*/
function htmlPreviousLink($page)
2016-02-25 19:18:35 +01:00
{
$html = '';
2016-02-25 19:18:35 +01:00
if ($page != 0)
2016-02-25 19:18:35 +01:00
{
$vars = $_GET;
$vars['page'] = $page - 1;
$html = '<a href=?' . http_build_query($vars) . '>Previous</a>';
2016-02-25 19:18:35 +01:00
}
return $html;
}
2016-02-25 19:18:35 +01:00
/**
* @param int $page
* @param int $maxPage
* @return string
*/
function htmlNextLink($page, $maxPage)
{
$html = '';
if ($page < $maxPage)
2016-02-25 19:18:35 +01:00
{
$vars = $_GET;
$vars['page'] = $page + 1;
$html = '<a href=?' . http_build_query($vars) . '>Next</a>&emsp;';
2016-02-25 19:18:35 +01:00
}
return $html;
2016-02-25 19:18:35 +01:00
}
/**
* @param int $page
* @param int $maxPage
* @return string
*/
2016-02-25 19:18:35 +01:00
function htmlPageNumbers($page, $maxPage)
{
$html = '';
for ($i = 0; $i <= $maxPage; $i++)
{
if (!empty($html))
{
$html .= ' ';
}
$humanPage = $i + 1;
$currPage = $i == $page;
if (!$currPage)
{
$vars = $_GET;
$vars['page'] = $i;
$html .= '<a href=?' . http_build_query($vars) . '>' . $humanPage . '</a>';
}
else
{
$html .= '<span style="font-weight:bold">' . $humanPage . '</span>';
}
}
return $html;
}
/**
* @param String $input
* @return String
*/
function removeBadCharacters($input)
{
return preg_replace('/[^A-Za-z0-9_\-]/', '_', $input);
}
2015-12-18 18:41:03 +01:00
$validIdentifier = isset($_GET['identifier']);
2016-02-25 19:18:35 +01:00
$page = isset($_GET['page']) ? $_GET['page'] : 0;
$error = "";
$identifier = null;
$filePath = null;
$snapshot = null;
$report = null;
2016-02-25 19:18:35 +01:00
$maxPage = null;
2015-12-18 18:41:03 +01:00
if ($validIdentifier)
{
$identifier = removeBadCharacters($_GET['identifier']); // prevents escaping
$filePath = dataDir . $identifier . '.json';
if (file_exists($filePath))
{
$dataArray = toDataArray($filePath);
$snapshot = toSnapshot($identifier, $dataArray);
$report = toReport($dataArray['report'], $snapshot->getPlayers());
2016-02-25 19:18:35 +01:00
$maxPage = ceil(count($snapshot->getMessages()) / messagesPerPage) - 1;
if ($page > $maxPage) {
$error = "Invalid page number.";
}
}
else
{
2015-12-18 18:41:03 +01:00
$validIdentifier = false;
2016-02-25 19:18:35 +01:00
$error = "Invalid identifier.";
}
}
?>
2015-12-16 01:22:55 +01:00
<!DOCTYPE html>
<html>
<head>
2015-12-16 01:22:55 +01:00
<script src="js/jquery.js"></script>
<link rel="stylesheet" href="css/bootstrap.min.css">
<script src="js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
<link rel="stylesheet" href="css/tiger.css">
<link href='https://fonts.googleapis.com/css?family=Crete+Round' rel='stylesheet' type='text/css'>
<link href='https://fonts.googleapis.com/css?family=Oswald' rel='stylesheet' type='text/css'>
<title>
2015-12-18 18:41:03 +01:00
<?php if ($validIdentifier) { ?>
Report #<?= $report->getId() ?>
<?php } else { ?>
Report System
<?php } ?>
2015-12-16 01:22:55 +01:00
&middot; Mineplex
</title>
2015-12-16 01:22:55 +01:00
<script>
$("#test").click(function (){
alert("test!");
});
</script>
</head>
<body>
2015-12-16 01:22:55 +01:00
<div id="wrapper">
<div id="header">
<img src="img/logo.png" height="70px" width="70px" />
<h1>Report System</h1>
<!-- <h2><i class="fa fa-camera"></i>&nbsp;&nbsp; Chat Snap</h2> -->
</div>
<div id="search">
2015-12-18 16:52:20 +01:00
<form id="identifier-input" name="identifier-input" action="view.php" method="get">
<div class="input-group">
<input name="identifier" type="text" class="form-control" placeholder="Enter an identifier provided in-game...">
<span class="input-group-btn">
<button class="btn btn-secondary" type="submit" form="identifier-input"><i class="fa fa-search"></i> Search</button>
</span>
</div>
</form>
2015-12-16 01:22:55 +01:00
</div>
2015-12-18 18:41:03 +01:00
2016-02-25 19:18:35 +01:00
<?php if (!empty($error)) { ?>
2015-12-18 19:11:25 +01:00
<div id="content" class="center-block" style="text-align: center; background-color: rgba(204, 34, 42, 0.52);">
<p class="error-oh-no" style="font-size: 60px;">What did you do?!?!?</p>
<img src="img/shaun.gif" />
2016-02-25 19:18:35 +01:00
<p class="error-oh-no" style="font-size: 40px;">Error: <?= $error ?></p>
2015-12-18 19:11:25 +01:00
<br>
2015-12-16 01:22:55 +01:00
</div>
2015-12-18 19:11:25 +01:00
<?php } else { ?>
<?php if (!isset($_GET['identifier'])) {
exit();
}?>
2015-12-18 19:11:25 +01:00
<div id="content">
<div>
2015-12-16 01:22:55 +01:00
<hr>
2015-12-18 19:11:25 +01:00
<h2 style="font-family: 'Oswald', sans-serif; text-align: center;">
Report #<?= $report->getId() ?>
</h2>
<hr>
</div>
<div class="row">
<div id="chat" class="col-lg-7">
<h4><i class="fa fa-comments"></i>&nbsp;&nbsp;&nbsp;Chat Log</h4>
<hr>
<div id="log" class="text-muted ">
<?php
$messages = $snapshot->getMessages();
2015-12-16 01:22:55 +01:00
2016-02-25 19:18:35 +01:00
$startIndex = $page * messagesPerPage;
$endIndex = $startIndex + messagesPerPage;
if ($endIndex > count($messages)) {
$endIndex = count($messages);
}
for ($i = $startIndex; $i < $endIndex; $i++) {
$message = $messages[$i];
2015-12-18 19:11:25 +01:00
$typeId = $message->getType();
$typeDisplayName = Message::$TYPE_DISPLAY_NAMES[$typeId];
$isPM = $typeId == Message::TYPE_PM;
2015-12-16 01:22:55 +01:00
2015-12-18 19:11:25 +01:00
// If this is a PM, then the "-> <recipient>" suffix will be applied.
$involved = $message->getSender()->getUsername() . ($isPM ? " -> " . $message->getRecipients()[0]->getUsername() : "");
?>
2015-12-16 01:22:55 +01:00
2015-12-18 19:11:25 +01:00
<span class="label <?php if($isPM) echo "label-primary chat pm"; else echo "label-info chat"; ?>" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;"><?= $typeDisplayName ?></span>
<span class="black"><?= $involved; ?>:</span> <?= $message->getMessage(); ?>
2015-12-16 01:22:55 +01:00
2016-02-25 19:18:35 +01:00
<?php if ($i != $endIndex){ // Don't break on the last element ?>
<br>
<?php } ?>
2015-12-18 19:11:25 +01:00
<?php } ?>
2016-02-25 19:18:35 +01:00
</div>
<div>
<?php
// TODO separate these into 3 divs aligned bottom-centre
// this ensures these links are in the same place every time
echo htmlPreviousLink($page);
echo htmlPageNumbers($page, $maxPage);
echo htmlNextLink($page, $maxPage);
?>
2015-12-16 01:22:55 +01:00
</div>
2015-12-18 19:11:25 +01:00
</div>
<div id="users" class="col-lg-5">
<h4><i class="fa fa-info-circle"></i>&nbsp;&nbsp;&nbsp;Information</h4>
<hr>
<div class="row">
<div class="col-lg-12">
2015-12-18 19:11:25 +01:00
<?php
$dateTime = $snapshot->getTimeGenerated();
$dateTimeFormatted = $dateTime->format('Y/m/d H:i:s T'); // originally m/d/Y H:i:s T
$age = approximateHumanInterval($dateTime->diff(new DateTime('now', $dateTime->getTimezone())));
2015-12-18 19:11:25 +01:00
$reporters = array();
2015-12-16 01:22:55 +01:00
2015-12-18 19:11:25 +01:00
foreach ($report->getReporters() as $reporter)
{
$reporters[count($reporters)] = $reporter->getUsername();
}
2015-12-16 01:22:55 +01:00
2015-12-18 19:11:25 +01:00
$reportersString = implode(", ", $reporters);
?>
2015-12-16 01:22:55 +01:00
<i class="fa fa-clock-o fa-fw"></i>
<span class="label label-pill label-default" title="<?= $dateTimeFormatted ?>"><?= $age . ' old' ?></span>
<br>
<i class="fa fa-user-plus fa-fw"></i>
<span class="label label-pill label-success">Reported by <?= $reportersString ?></span>
<br>
<i class="fa fa-user-times fa-fw"></i>
<span class="label label-pill label-danger">Suspect is <?= $report->getSuspect()->getUsername() ?></span>
<br>
<i class="fa fa-gavel fa-fw"></i>
<span class="label label-pill label-warning">
<?php
$handler = $report->getHandler();
echo $handler != null ? "Staff Member assigned is " . $handler->getUsername() : "No Staff Member assigned";
?>
</span>
<br>
2015-12-18 19:11:25 +01:00
</div>
2015-12-16 01:22:55 +01:00
</div>
2015-12-18 19:11:25 +01:00
<br>
<h4><i class="fa fa-users"></i>&nbsp;&nbsp;&nbsp;Users</h4>
<hr>
<?php foreach($snapshot->getPlayers() as $player): ?>
<img src="http://cravatar.eu/avatar/<?= $player->getUUID() ?>/55.png" class="pull-left" />
&nbsp;&nbsp;<b class="name"><?= $player->getUsername() ?></b> <span class="label label-staff name"><?= $player->getRank() ?></span><br> <!-- TODO different styling for different ranks -->&nbsp;
2015-12-18 19:11:25 +01:00
<code style="font-size: 11px;"><?= $player->getUUID() ?></code>
<br><br>
<?php endforeach; ?>
2015-12-16 01:22:55 +01:00
</div>
</div>
</div>
2015-12-18 19:11:25 +01:00
<?php } ?>
<div id="footer">
2015-12-16 01:22:55 +01:00
<a href="http://www.mineplex.com"><img src="img/logo-full.png" width="225px" /></a>
<div class="btn-group pull-right indent-link" style="font-family: 'Crete Round', serif; padding-top: 10px;">
<a href="http://www.mineplex.com" class="btn btn-link btn-small text-muted">Home</a>
<a href="http://www.mineplex.com/shop/" class="btn btn-link btn-small text-muted">Shop</a>
<a href="http://www.mineplex.com/forums/" class="btn btn-link btn-small text-muted">Forums</a>
<a href="http://www.mineplex.com/supporthub/" class="btn btn-link btn-small text-muted">Support</a>
</div>
</div>
</div>
</body>
</html>
<?php
2016-02-25 19:18:35 +01:00
foreach ($connections as $connection) {
$connection->close();
}
?>