309 lines
10 KiB
PHP
309 lines
10 KiB
PHP
<?php
|
|
session_start();
|
|
|
|
// Webchat data dir
|
|
$webchatdir='/var/games/minetest-server/.minetest/worlds/SecklSurvival/webchat';
|
|
|
|
// Generate a unique color for every username based on its crc32 hash sum
|
|
function playercolor($player,$color) {
|
|
list($r1,$r2,$g1,$g2,$b1,$b2)=str_split(dechex(crc32($player)),1);
|
|
if ($color=="r") {
|
|
return 'ff'.$g1.$g2.$b1.$b2;
|
|
} elseif ($color=="g") {
|
|
return $r1.$r2.'ff'.$b1.$b2;
|
|
} elseif ($color=="b") {
|
|
return $r1.$r2.$g1.$g2.'ff';
|
|
}
|
|
}
|
|
|
|
if (empty($_SESSION['player'])) {
|
|
|
|
// Not logged in => Please login first
|
|
header('Location: /login/');
|
|
exit();
|
|
|
|
} elseif (isset($_GET['lastchatline']) and isset($_GET['lastservline'])) {
|
|
|
|
// Send/update chat history to browser
|
|
|
|
$mt_socket=socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
|
|
socket_connect($mt_socket,'127.0.0.1','29999');
|
|
|
|
$cmd=json_encode(array('lua'=>"webchat.ping('".$_SESSION['player']."')",'id'=>'chat_ping'))."\n";
|
|
socket_write($mt_socket,$cmd,strlen($cmd));
|
|
$reply=socket_read($mt_socket,1048576);
|
|
|
|
socket_close($mt_socket);
|
|
|
|
$chatdata=array();
|
|
$chatlines=0;
|
|
$loglines=file($webchatdir.'/chat.log');
|
|
|
|
foreach ($loglines as $chatline) {
|
|
|
|
$chatlines++;
|
|
|
|
// Return all lines after $_GET['lastchatline']
|
|
if ($chatlines > $_GET['lastchatline']) {
|
|
|
|
// Edit line
|
|
list($timestamp,$user,$text)=explode("\t",htmlspecialchars(trim($chatline),ENT_QUOTES));
|
|
$date=date('Y-m-d',$timestamp);
|
|
$time=date('H:i:s T',$timestamp);
|
|
$color=playercolor($user,"b");
|
|
$chatline='<tr style="color: #'.$color.'"><td id="u"><'.$user.'></td><td><span id="d"> '.$date.'</span><span id="t"> '.$time.'</span></td></tr><tr style="color: #'.$color.'"><td id="txt" colspan="2">'.$text.'</td></tr>';
|
|
|
|
array_push($chatdata,$chatline);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$dmdata=array();
|
|
$dmlines=0;
|
|
$loglines=file($webchatdir.'/playerdata/'.$_SESSION['player'].'/dm.log');
|
|
|
|
foreach ($loglines as $dmline) {
|
|
|
|
$dmlines++;
|
|
|
|
// Return all lines after $_GET['lastdmline']
|
|
if ($dmlines > $_GET['lastdmline']) {
|
|
|
|
// Edit line
|
|
list($timestamp,$fromto,$user,$text)=explode("\t",htmlspecialchars(trim($dmline),ENT_QUOTES));
|
|
$date=date('Y-m-d',$timestamp);
|
|
$time=date('H:i:s T',$timestamp);
|
|
if ($user=="+error+") {
|
|
if ($timestamp > time()-300) {
|
|
// Show only error messages from the last 5 min
|
|
$color='ff0000';
|
|
$dmline='<tr style="color: #'.$color.'"><td id="err" colspan="2"><dfn class="wchat-tooltip" wchat-tooltip-text="Valid commands are: /msg <player> <message>, /me <message>">Error: '.$text.'</dfn></td></tr>';
|
|
array_push($dmdata,$dmline);
|
|
}
|
|
} else {
|
|
$color=playercolor($user,"r");
|
|
$dmline='<tr style="color: #'.$color.'"><td id="u">DM '.$fromto.' '.$user.':</td><td><span id="d"> '.$date.'</span><span id="t"> '.$time.'</span></td></tr><tr style="color: #'.$color.'"><td id="txt" colspan="2">'.$text.'</td></tr>';
|
|
array_push($dmdata,$dmline);
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$servdata=array();
|
|
$servlines=0;
|
|
$loglines=file($webchatdir.'/server.log');
|
|
|
|
foreach ($loglines as $servline) {
|
|
|
|
$servlines++;
|
|
|
|
// Return all lines after $_GET['lastservline']
|
|
if ($servlines > $_GET['lastservline']) {
|
|
|
|
// Edit line
|
|
list($timestamp,$text)=explode("\t",htmlspecialchars(trim($servline),ENT_QUOTES));
|
|
$date=date('Y-m-d',$timestamp);
|
|
$time=date('H:i:s T',$timestamp);
|
|
$servline='<tr><td id="txt">'.$text.'</td><td><span id="d"> '.$date.'</span><span id="t"> '.$time.'</span></td></tr>';
|
|
|
|
array_push($servdata,$servline);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
echo json_encode(array("chatlines"=>$chatlines,"servlines"=>$servlines,"dmlines"=>$dmlines,"chatdata"=>$chatdata,"servdata"=>$servdata,"dmdata"=>$dmdata));
|
|
|
|
exit();
|
|
|
|
} elseif (!empty($_POST['msg'])) {
|
|
|
|
// Send chat message
|
|
|
|
$mt_socket=socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
|
|
socket_connect($mt_socket,'127.0.0.1','29999');
|
|
|
|
// Sanitize $message
|
|
$message=addslashes($_POST['msg']); // Escape some special characters ('"\)
|
|
$message=trim($message," \n\r\t\v\0\\"); // Remove some special chars from the beginning and end
|
|
$message=substr($message,0,500); // Max length 500 chars
|
|
|
|
$cmd=json_encode(array('lua'=>"webchat.receive_msg('".$_SESSION['player']."','".$message."')",'id'=>'chat_msg'))."\n";
|
|
socket_write($mt_socket,$cmd,strlen($cmd));
|
|
$reply=socket_read($mt_socket,1048576);
|
|
|
|
socket_close($mt_socket);
|
|
|
|
// Send HTTP 204 so that the browser stays on the page
|
|
ob_start();
|
|
header("HTTP/1.1 204 NO CONTENT");
|
|
header("Cache-Control: no-cache, no-store, must-revalidate");
|
|
header("Pragma: no-cache");
|
|
header("Expires: 0");
|
|
ob_end_flush();
|
|
|
|
exit();
|
|
|
|
}
|
|
|
|
?>
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title>Minetest Web Chat</title>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<link rel="stylesheet" href="/style.css">
|
|
<script src="jquery.min.js"></script>
|
|
<script>
|
|
|
|
function ToggleChat() {
|
|
var chlog=document.getElementById("wchat-chatlog");
|
|
var chbut=document.getElementById("wchat-chswbt-ch");
|
|
var dmlog=document.getElementById("wchat-dmlog");
|
|
var dmbut=document.getElementById("wchat-chswbt-dm");
|
|
if (chlog.style.display==="none") {
|
|
chlog.style.display="flex";
|
|
chlog.style.width="50%";
|
|
chlog.style.float="left";
|
|
chbut.style.color="#000";
|
|
chbut.style.background="#2c9cdc";
|
|
dmlog.style.display="flex";
|
|
dmlog.style.width="50%";
|
|
dmbut.style.color="#000";
|
|
dmbut.style.background="#2c9cdc";
|
|
} else {
|
|
chlog.style.display="none";
|
|
chbut.style.color="inherit";
|
|
chbut.style.background="inherit";
|
|
dmlog.style.display="flex";
|
|
dmlog.style.width="100%";
|
|
dmbut.style.color="#000";
|
|
dmbut.style.background="#2c9cdc";
|
|
}
|
|
}
|
|
|
|
function ToggleDM() {
|
|
var dmlog=document.getElementById("wchat-dmlog");
|
|
var dmbut=document.getElementById("wchat-chswbt-dm");
|
|
var chlog=document.getElementById("wchat-chatlog");
|
|
var chbut=document.getElementById("wchat-chswbt-ch");
|
|
if (dmlog.style.display==="none") {
|
|
chlog.style.display="flex";
|
|
chlog.style.width="50%";
|
|
chlog.style.float="left";
|
|
chbut.style.color="#000";
|
|
chbut.style.background="#2c9cdc";
|
|
dmlog.style.display="flex";
|
|
dmlog.style.width="50%";
|
|
dmbut.style.color="#000";
|
|
dmbut.style.background="#2c9cdc";
|
|
} else {
|
|
chlog.style.display="flex";
|
|
chlog.style.width="100%";
|
|
chlog.style.float="none";
|
|
chbut.style.color="#000";
|
|
chbut.style.background="#2c9cdc";
|
|
dmlog.style.display="none";
|
|
dmbut.style.color="inherit";
|
|
dmbut.style.background="inherit";
|
|
}
|
|
}
|
|
|
|
function playSound(url) {
|
|
const audio=new Audio(url);
|
|
audio.play();
|
|
}
|
|
|
|
function scrollDown() {$("html, body").animate({scrollTop: $(document).height()}, "fast")}
|
|
|
|
function SelectChatMsg() {document.getElementsByName("msg")[0].select()}
|
|
|
|
function Logout() {window.location.replace('/login/?logout')}
|
|
|
|
lastChatLine=0;
|
|
lastDmLine=0;
|
|
lastServLine=0;
|
|
scrollOnce=true;
|
|
|
|
$(document).ready(function() {
|
|
// Scroll to bottom once after the page has loaded
|
|
scrollDown();
|
|
});
|
|
|
|
// Update the chat/dm/server history
|
|
$.ajaxSetup({timeout: 1500}); // Timeout 1.5 sec for getJSON
|
|
setInterval("updateHist()",2000); // Update history every 2 sec
|
|
function updateHist() {
|
|
$.getJSON('?lastchatline='+lastChatLine+'&lastdmline='+lastDmLine+'&lastservline='+lastServLine,function(data) {
|
|
if (lastChatLine!=data.chatlines || lastDmLine!=data.dmlines || lastServLine!=data.servlines) {
|
|
// Play sound and scroll to bottom on incoming message
|
|
playSound('snd-msg.ogg');
|
|
scrollDown();
|
|
}
|
|
lastChatLine=data.chatlines;
|
|
lastDmLine=data.dmlines;
|
|
lastServLine=data.servlines;
|
|
$.each(data.chatdata,function(key,value) {
|
|
$("#wchat-chatlog").append(''+value);
|
|
});
|
|
$.each(data.dmdata,function(key,value) {
|
|
$("#wchat-dmlog").append(''+value);
|
|
});
|
|
$.each(data.servdata,function(key,value) {
|
|
$("#wchat-servlog").append(''+value);
|
|
});
|
|
// Scroll to bottom once when chat history has been loaded
|
|
if (scrollOnce) {
|
|
scrollDown();
|
|
scrollOnce=false;
|
|
}
|
|
});
|
|
}
|
|
|
|
</script>
|
|
</head>
|
|
<body>
|
|
|
|
<div class="wchat-content">
|
|
|
|
<h3 id="help">Minetest Web Chat</h3>
|
|
|
|
<p>The chat works the same as the Minetest in-game chat:
|
|
<ul>
|
|
<li>Chat and /me messages will be sent to all connected players (Minetest and Web Chat).</li>
|
|
<li>Direct messages (DM) to one player can be sent with /msg <player> <message>.</li>
|
|
</ul>
|
|
See the <a href="https://wiki.minetest.net/Chat#Sending_messages" target="_blank">Minetest Wiki</a> for details.
|
|
Chat and /me messages are shown on the left side, DM on the right.
|
|
</p>
|
|
<p>
|
|
You can hide and unhide the columns by clicking on the green buttons below.
|
|
</p>
|
|
|
|
<table class="wchat-chatout" id="wchat-chatlog"></table>
|
|
<table class="wchat-chatout" id="wchat-dmlog"></table>
|
|
|
|
<table id="wchat-chatsw"><tr><td class="wchat-chswbt" id="wchat-chswbt-ch" onclick="ToggleChat()">Chat</td><td class="wchat-chswbt" id="wchat-chswbt-dm" onclick="ToggleDM()"><span id="long">Direct Messages</span><span id="short">DM</span></td></tr></table>
|
|
|
|
<table id="wchat-chatin"><tbody>
|
|
<tr><td>
|
|
<form method="POST" action="" onsubmit="SelectChatMsg()">
|
|
<?php
|
|
echo ' <p id="u"><'.$_SESSION['player'].'> <a href="#help">?</a></p>'."\n";
|
|
?>
|
|
<p><input type="text" required minlength="1" name="msg" placeholder="Type your message here and press enter..." autofocus autocomplete="off"></p>
|
|
<p><input style="width: 65%; margin-right: 5px" type="submit" value="Send"><input style="width: calc(100% - 65% - 10px); margin-left: 5px" type="button" value="Logout" onclick="Logout()"></p>
|
|
</form>
|
|
</td></tr>
|
|
</tbody></table>
|
|
|
|
<table class="wchat-chatout" id="wchat-servlog"></table>
|
|
|
|
</div>
|
|
|
|
</body>
|
|
</html>
|