Compare commits

...

12 Commits

4 changed files with 148 additions and 159 deletions

View File

@ -1,3 +1,14 @@
Version 1.20.6 - Jul. 23, 2016
Simplify ignore logic + disallow ignoring chatters with higher status
Delete messages based on public message limit, no buffer for private ones needed
Allow deleting messages by name, when only PMs were sent
Version 1.20.5 - Jul. 19, 2016
Check permission before selectively deleting a message.
Version 1.20.4 - Jul. 12, 2016
Third attempt to fix the same bug
Version 1.20.3 - Jul. 10, 2016
Yesterdays bugfix broke more than it fixed, refixed.

294
chat.php
View File

@ -18,15 +18,29 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* status codes
* 0 - Kicked/Banned
* 1 - Guest
* 2 - Applicant
* 3 - Member
* 4 - System message
* 5 - Moderator
* 6 - Super-Moderator
* 7 - Admin
* 8 - Super-Admin
* 9 - Private messages
*/
send_headers();
// initialize and load variables/configuration
$A=array();// All registered members
$A=array();// All registered members [display name, style, status, nickname]
$C=array();// Configuration
$F=array();// Fonts
$H=array();// HTML-stuff
$I=array();// Translations
$L=array();// Languages
$P=array();// All present users
$P=array();// All present users [display name, style, status, nickname]
$U=array();// This user data
$countmods=0;// Present moderators
$db;// Database connection
@ -82,7 +96,7 @@ function route(){
check_session();
if($_REQUEST['what']==='all'){
if(isSet($_REQUEST['confirm'])){
del_all_messages($U['nickname'], 10, $U['entry']);
del_all_messages($U['nickname'], $U['status']==1 ? $U['entry'] : 0);
}else{
send_del_confirm();
}
@ -142,7 +156,7 @@ function route(){
}
function route_admin(){
global $U;
global $U, $db;
if($U['status']<5){
send_access_denied();
}
@ -151,11 +165,15 @@ function route_admin(){
if($_REQUEST['what']==='choose'){
send_choose_messages();
}elseif($_REQUEST['what']==='selected'){
clean_selected();
clean_selected($U['status'], $U['nickname']);
}elseif($_REQUEST['what']==='room'){
clean_room();
}elseif($_REQUEST['what']==='nick'){
del_all_messages($_REQUEST['nickname'], $U['status'], 0);
$stmt=$db->prepare('SELECT * FROM ' . PREFIX . 'members WHERE nickname=? AND status>=?;');
$stmt->execute([$_REQUEST['nickname'], $U['status']]);
if(!$stmt->fetch(PDO::FETCH_ASSOC)){
del_all_messages($_REQUEST['nickname'], 0);
}
}
}elseif($_REQUEST['do']==='kick'){
if(isSet($_REQUEST['name'])){
@ -214,7 +232,7 @@ function route_setup(){
$C['bool_settings']=array('suguests', 'imgembed', 'timestamps', 'trackip', 'memkick', 'forceredirect', 'incognito', 'sendmail', 'modfallback', 'disablepm', 'eninbox');
$C['colour_settings']=array('colbg', 'coltxt');
$C['msg_settings']=array('msgenter', 'msgexit', 'msgmemreg', 'msgsureg', 'msgkick', 'msgmultikick', 'msgallkick', 'msgclean', 'msgsendall', 'msgsendmem', 'msgsendmod', 'msgsendadm', 'msgsendprv');
$C['number_settings']=array('memberexpire', 'guestexpire', 'kickpenalty', 'entrywait', 'captchatime', 'messageexpire', 'messagelimit', 'keeplimit', 'maxmessage', 'maxname', 'minpass', 'defaultrefresh', 'numnotes');
$C['number_settings']=array('memberexpire', 'guestexpire', 'kickpenalty', 'entrywait', 'captchatime', 'messageexpire', 'messagelimit', 'maxmessage', 'maxname', 'minpass', 'defaultrefresh', 'numnotes');
$C['textarea_settings']=array('rulestxt', 'css', 'disabletext');
$C['text_settings']=array('dateformat', 'captchachars', 'redirect', 'chatname', 'mailsender', 'mailreceiver');
$C['settings']=array_merge(array('guestaccess', 'englobalpass', 'globalpass', 'captcha', 'dismemcaptcha', 'topic', 'guestreg', 'defaulttz'), $C['bool_settings'], $C['colour_settings'], $C['msg_settings'], $C['number_settings'], $C['textarea_settings'], $C['text_settings']); // All settings in the database
@ -837,14 +855,6 @@ function send_alogin(){
print_end();
}
function sort_names(&$names){
$keys=[];
foreach($names as $k => $v){
$keys[]=(string) $k;
}
array_multisort(array_map('strtolower', $keys), SORT_ASC, SORT_STRING, $names);
}
function send_admin($arg=''){
global $A, $H, $I, $P, $U, $db;
$ga=(int) get_setting('guestaccess');
@ -870,7 +880,7 @@ function send_admin($arg=''){
echo "<label for=\"room\">$I[room]</label></td><td>&nbsp;</td><td><input type=\"radio\" name=\"what\" id=\"choose\" value=\"choose\" checked>";
echo "<label for=\"choose\">$I[selection]</label></td><td>&nbsp;</td></tr><tr><td colspan=\"3\"><input type=\"radio\" name=\"what\" id=\"nick\" value=\"nick\">";
echo "<label for=\"nick\">$I[cleannick] </label><select name=\"nickname\" size=\"1\"><option value=\"\">$I[choose]</option>";
$stmt=$db->prepare('SELECT poster FROM ' . PREFIX . 'messages WHERE poststatus<9 AND delstatus<? GROUP BY poster;');
$stmt=$db->prepare('SELECT poster FROM ' . PREFIX . 'messages WHERE delstatus<? GROUP BY poster;');
$stmt->execute(array($U['status']));
while($nick=$stmt->fetch(PDO::FETCH_NUM)){
echo "<option value=\"$nick[0]\">$nick[0]</option>";
@ -950,18 +960,18 @@ function send_admin($arg=''){
read_members();
sort_names($A);
foreach($A as $member){
echo "<option value=\"$member[0]\" style=\"$member[2]\">$member[0]";
if($member[1]==0){
echo "<option value=\"$member[0]\" style=\"$member[1]\">$member[0]";
if($member[2]==0){
echo ' (!)';
}elseif($member[1]==2){
}elseif($member[2]==2){
echo ' (G)';
}elseif($member[1]==5){
}elseif($member[2]==5){
echo ' (M)';
}elseif($member[1]==6){
}elseif($member[2]==6){
echo ' (SM)';
}elseif($member[1]==7){
}elseif($member[2]==7){
echo ' (A)';
}elseif($member[1]==8){
}elseif($member[2]==8){
echo ' (SA)';
}
echo '</option>';
@ -982,7 +992,7 @@ function send_admin($arg=''){
frmadm('passreset');
echo "<table class=\"right-table\"><td><select name=\"name\" size=\"1\"><option value=\"\">$I[choose]</option>";
foreach($A as $member){
echo "<option value=\"$member[0]\" style=\"$member[2]\">$member[0]</option>";
echo "<option value=\"$member[0]\" style=\"$member[1]\">$member[0]</option>";
}
echo '</select></td><td><input type="password" name="pass"></td><td>'.submit($I['change']).'</td></tr></table></form></td></tr></table></td></tr>';
thr();
@ -1620,29 +1630,19 @@ function send_post(){
}
$disablepm=(bool) get_setting('disablepm');
if(!$disablepm){
$ignored=array();
$ignore=get_ignored();
foreach($ignore as $ign){
if($ign['ignored']===$U['nickname']){
$ignored[]=$ign['by'];
}
if($ign['by']===$U['nickname']){
$ignored[]=$ign['ignored'];
}
}
$stmt=$db->prepare('SELECT nickname, style, status FROM ' . PREFIX . 'members WHERE eninbox!=0 AND eninbox<=? AND nickname NOT IN (SELECT nickname FROM ' . PREFIX . 'sessions WHERE incognito=0) AND nickname NOT IN (SELECT ign FROM ' . PREFIX . 'ignored WHERE ignby=?) AND nickname NOT IN (SELECT ignby FROM ' . PREFIX . 'ignored WHERE ign=?);');
$stmt->execute(array($U['status'], $U['nickname'], $U['nickname']));
while($tmp=$stmt->fetch(PDO::FETCH_ASSOC)){
$P[$tmp['nickname']]=["$tmp[nickname] $I[offline]", $tmp['style'], $tmp['status']];
$P[$tmp['nickname']]=["$tmp[nickname] $I[offline]", $tmp['style'], $tmp['status'], $tmp['nickname']];
}
sort_names($P);
foreach($P as $name => $user){
if($U['nickname']!==$user[0] && !in_array($user[0], $ignored)){
foreach($P as $user){
if($U['nickname']!==$user[3]){
echo '<option ';
if($_REQUEST['sendto']==$name){
if($_REQUEST['sendto']==$user[3]){
echo 'selected ';
}
echo "value=\"$name\" style=\"$user[1]\">$user[0]</option>";
echo "value=\"$user[3]\" style=\"$user[1]\">$user[0]</option>";
}
}
}
@ -1707,44 +1707,34 @@ function send_profile($arg=''){
echo "<$H[form]>$H[commonform]".hidden('action', 'profile').hidden('do', 'save')."<h2>$I[profile]</h2><i>$arg</i><table class=\"center-table\">";
thr();
sort_names($P);
$ignored=array();
$ignore=get_ignored();
foreach($ignore as $ign){
if($ign['by']===$U['nickname']){
$ignored[]=$ign['ignored'];
}
$ignored=[];
$stmt=$db->prepare('SELECT ign FROM ' . PREFIX . 'ignored WHERE ignby=?;');
$stmt->execute([$U['nickname']]);
while($tmp=$stmt->fetch(PDO::FETCH_ASSOC)){
$ignored[]=$tmp['ign'];
}
if(count($ignored)>0){
echo "<tr><td><table class=\"left-table\"><tr><th>$I[unignore]</th><td class=\"right\">";
echo "<select name=\"unignore\" size=\"1\"><option value=\"\">$I[choose]</option>";
foreach($ignored as $ign){
$style='';
foreach($P as $user){
if($ign===$user[0]){
$style=" style=\"$user[1]\"";
break;
}
}
echo "<option value=\"$ign\"$style>$ign</option>";
echo "<option value=\"$ign\">$ign</option>";
}
echo '</select></td></tr></table></td></tr>';
thr();
}
if(count($P)-count($ignored)>1){
echo "<tr><td><table class=\"left-table\"><tr><th>$I[ignore]</th><td class=\"right\">";
echo "<select name=\"ignore\" size=\"1\"><option value=\"\">$I[choose]</option>";
$stmt=$db->query('SELECT poster FROM ' . PREFIX . 'messages GROUP BY poster;');
while($nick=$stmt->fetch(PDO::FETCH_NUM)){
$nicks[]=$nick[0];
}
foreach($P as $user){
if($U['nickname']!==$user[0] && !in_array($user[0], $ignored) && in_array($user[0], $nicks)){
echo "<option value=\"$user[0]\" style=\"$user[1]\">$user[0]</option>";
}
}
echo '</select></td></tr></table></td></tr>';
thr();
echo "<tr><td><table class=\"left-table\"><tr><th>$I[ignore]</th><td class=\"right\">";
echo "<select name=\"ignore\" size=\"1\"><option value=\"\">$I[choose]</option>";
$stmt=$db->query('SELECT poster FROM ' . PREFIX . 'messages GROUP BY poster;');
while($nick=$stmt->fetch(PDO::FETCH_NUM)){
$nicks[]=$nick[0];
}
foreach($P as $user){
if($U['nickname']!==$user[0] && in_array($user[0], $nicks) && $user[2]<=$U['status']){
echo "<option value=\"$user[0]\" style=\"$user[1]\">$user[0]</option>";
}
}
echo '</select></td></tr></table></td></tr>';
thr();
echo "<tr><td><table class=\"left-table\"><tr><th>$I[refreshrate]</th><td class=\"right\">";
echo "<input type=\"number\" name=\"refresh\" size=\"3\" maxlength=\"3\" min=\"5\" max=\"150\" value=\"$U[refresh]\"></td></tr></table></td></tr>";
thr();
@ -2048,9 +2038,9 @@ function create_session($setup){
if(!$stmt->fetch(PDO::FETCH_BOUND)){
send_error($I['captchaexpire']);
}
$timeout=time()-get_setting('captchatime');
$stmt=$db->prepare('DELETE FROM ' . PREFIX . 'captcha WHERE id=? OR time<?;');
$stmt->execute(array($_REQUEST['challenge'], $timeout));
$time=time();
$stmt=$db->prepare('DELETE FROM ' . PREFIX . 'captcha WHERE id=? OR time<(?-(SELECT value FROM ' . PREFIX . "settings WHERE setting='captchatime'));");
$stmt->execute(array($_REQUEST['challenge'], $time));
}else{
if(!$code=$memcached->get(DBNAME . '-' . PREFIX . "captcha-$_REQUEST[challenge]")){
send_error($I['captchaexpire']);
@ -2122,7 +2112,7 @@ function write_new_session(){
if($U['status']>=3 && !$U['incognito']){
add_system_message(sprintf(get_setting('msgenter'), style_this($U['nickname'], $U['style'])));
}
$P[$U['nickname']]=[$U['nickname'], $U['style'], $U['status']];
$P[$U['nickname']]=[$U['nickname'], $U['style'], $U['status'], $U['nickname']];
}
}
@ -2235,7 +2225,7 @@ function kick_chatter($names, $mes, $purge){
if(($temp[0]===$U['nickname'] && $U['nickname']===$name) || ($U['status']>$temp[2] && (($temp[0]===$name && $temp[2]>0) || ($name==='&' && $temp[2]==1)))){
$stmt->execute(array($time, $mes, $name));
if($purge){
del_all_messages($name, 10, 0);
del_all_messages($name, 0);
}
$lonick.=style_this($name, $temp[1]).', ';
++$i;
@ -2323,10 +2313,9 @@ function get_nowchatting(){
function parse_sessions(){
global $P, $U, $countmods, $db;
// delete old sessions
$guestexpire=time()-60*get_setting('guestexpire');
$memberexpire=time()-60*get_setting('memberexpire');
$result=$db->prepare('SELECT nickname, status FROM ' . PREFIX . 'sessions WHERE (status<=2 AND lastpost<?) OR (status>2 AND lastpost<?);');
$result->execute(array($guestexpire, $memberexpire));
$time=time();
$result=$db->prepare('SELECT nickname, status FROM ' . PREFIX . 'sessions WHERE (status<=2 AND lastpost<(?-60*(SELECT value FROM ' . PREFIX . "settings WHERE setting='guestexpire'))) OR (status>2 AND lastpost<(?-60*(SELECT value FROM " . PREFIX . "settings WHERE setting='memberexpire')));");
$result->execute(array($time, $time));
if($tmp=$result->fetchAll(PDO::FETCH_ASSOC)){
$stmt=$db->prepare('DELETE FROM ' . PREFIX . 'sessions WHERE nickname=?;');
$stmt1=$db->prepare('UPDATE ' . PREFIX . "messages SET poster='' WHERE poster=? AND poststatus=9;");
@ -2355,10 +2344,15 @@ function parse_sessions(){
// load other sessions
$countmods=0;
$P=array();
$stmt=$db->query('SELECT nickname, style, status, incognito FROM ' . PREFIX . 'sessions WHERE entry!=0 AND status>0 ORDER BY status DESC, lastpost DESC;');
if(isSet($U['nickname'])){
$stmt=$db->prepare('SELECT nickname, style, status, incognito FROM ' . PREFIX . 'sessions WHERE entry!=0 AND status>0 AND nickname NOT IN (SELECT ign FROM '. PREFIX . 'ignored WHERE ignby=?) AND nickname NOT IN (SELECT ignby FROM '. PREFIX . 'ignored WHERE ign=?) ORDER BY status DESC, lastpost DESC;');
$stmt->execute([$U['nickname'], $U['nickname']]);
}else{
$stmt=$db->query('SELECT nickname, style, status, incognito FROM ' . PREFIX . 'sessions WHERE entry!=0 AND status>0 ORDER BY status DESC, lastpost DESC;');
}
while($temp=$stmt->fetch(PDO::FETCH_ASSOC)){
if(!$temp['incognito']){
$P[$temp['nickname']]=[$temp['nickname'], $temp['style'], $temp['status']];
$P[$temp['nickname']]=[$temp['nickname'], $temp['style'], $temp['status'], $temp['nickname']];
}
if($temp['status']>=5){
++$countmods;
@ -2390,9 +2384,7 @@ function read_members(){
global $A, $db;
$result=$db->query('SELECT * FROM ' . PREFIX . 'members;');
while($temp=$result->fetch(PDO::FETCH_ASSOC)){
$A[$temp['nickname']][0]=$temp['nickname'];
$A[$temp['nickname']][1]=$temp['status'];
$A[$temp['nickname']][2]=$temp['style'];
$A[$temp['nickname']]=[$temp['nickname'], $temp['style'], $temp['status'], $temp['nickname']];
}
}
@ -2605,7 +2597,7 @@ function amend_profile(){
}
function save_profile(){
global $I, $U, $db;
global $I, $P, $U, $db;
amend_profile();
$stmt=$db->prepare('UPDATE ' . PREFIX . 'sessions SET refresh=?, style=?, boxwidth=?, boxheight=?, bgcolour=?, notesboxwidth=?, notesboxheight=?, timestamps=?, embed=?, incognito=?, nocache=?, tz=?, eninbox=? WHERE session=?;');
$stmt->execute(array($U['refresh'], $U['style'], $U['boxwidth'], $U['boxheight'], $U['bgcolour'], $U['notesboxwidth'], $U['notesboxheight'], $U['timestamps'], $U['embed'], $U['incognito'], $U['nocache'], $U['tz'], $U['eninbox'], $U['session']));
@ -2618,8 +2610,10 @@ function save_profile(){
$stmt->execute(array($_REQUEST['unignore'], $U['nickname']));
}
if(!empty($_REQUEST['ignore'])){
$stmt=$db->prepare('INSERT INTO ' . PREFIX . 'ignored (ign, ignby) VALUES (?, ?);');
$stmt->execute(array($_REQUEST['ignore'], $U['nickname']));
if($_REQUEST['ignore']!==$U['nickname'] && $P[$_REQUEST['ignore']][2]<=$U['status']){
$stmt=$db->prepare('INSERT INTO ' . PREFIX . 'ignored (ign, ignby) VALUES (?, ?);');
$stmt->execute(array($_REQUEST['ignore'], $U['nickname']));
}
}
if($U['status']>1 && !empty($_REQUEST['newpass'])){
if(!valid_pass($_REQUEST['newpass'])){
@ -2687,7 +2681,7 @@ function add_user_defaults(){
global $U;
$U['refresh']=get_setting('defaultrefresh');
$U['bgcolour']=get_setting('colbg');
if(!isSet($_REQUEST['colour']) || !preg_match('/^[a-f0-9]{6}$/i', $_REQUEST['colour'])){
if(!isSet($_REQUEST['colour']) || !preg_match('/^[a-f0-9]{6}$/i', $_REQUEST['colour']) || abs(greyval($_REQUEST['colour'])-greyval(get_setting('colbg')))<75){
do{
$U['colour']=sprintf('%02X', mt_rand(0, 256)).sprintf('%02X', mt_rand(0, 256)).sprintf('%02X', mt_rand(0, 256));
}while(abs(greyval($U['colour'])-greyval(get_setting('colbg')))<75);
@ -2712,7 +2706,7 @@ function add_user_defaults(){
function validate_input(){
global $P, $U, $db;
$inboxes=[];
$inbox=false;
$maxmessage=get_setting('maxmessage');
$U['message']=substr($_REQUEST['message'], 0, $maxmessage);
$U['rejected']=substr($_REQUEST['message'], $maxmessage);
@ -2742,7 +2736,6 @@ function validate_input(){
}
$U['message']=trim($U['message']);
$U['message']=preg_replace('/\s+/', ' ', $U['message']);
$U['delstatus']=$U['status'];
$U['recipient']='';
if($_REQUEST['sendto']==='*'){
$U['poststatus']='1';
@ -2760,22 +2753,17 @@ function validate_input(){
if(get_setting('disablepm')){
return;
}
$stmt=$db->prepare('SELECT * FROM ' . PREFIX . 'ignored WHERE (ignby=? AND ign=?) OR (ignby=? AND ign=?);');
$stmt->execute(array($U['nickname'], $_REQUEST['sendto'], $_REQUEST['sendto'], $U['nickname']));
if(!$stmt->fetch(PDO::FETCH_NUM)){
$stmt=$db->prepare('SELECT nickname, style, status FROM ' . PREFIX . 'members WHERE eninbox!=0 AND eninbox<=? AND nickname NOT IN (SELECT nickname FROM ' . PREFIX . 'sessions WHERE incognito=0) AND nickname NOT IN (SELECT ign FROM ' . PREFIX . 'ignored WHERE ignby=?) AND nickname NOT IN (SELECT ignby FROM ' . PREFIX . 'ignored WHERE ign=?);');
$stmt->execute(array($U['status'], $U['nickname'], $U['nickname']));
while($tmp=$stmt->fetch(PDO::FETCH_ASSOC)){
$P[$tmp['nickname']]=[$tmp['nickname'], $tmp['style'], $tmp['status']];
$inboxes[$tmp['nickname']]=true;
}
if(isSet($P[$_REQUEST['sendto']])){
$U['recipient']=$P[$_REQUEST['sendto']][0];
$U['displayrecp']=style_this($U['recipient'], $P[$_REQUEST['sendto']][1]);
$U['poststatus']='9';
$U['delstatus']='9';
$U['displaysend']=sprintf(get_setting('msgsendprv'), style_this($U['nickname'], $U['style']), $U['displayrecp']);
}
$stmt=$db->prepare('SELECT nickname, style, status FROM ' . PREFIX . 'members WHERE nickname=? AND eninbox!=0 AND eninbox<=? AND nickname NOT IN (SELECT nickname FROM ' . PREFIX . 'sessions WHERE incognito=0) AND nickname NOT IN (SELECT ign FROM ' . PREFIX . 'ignored WHERE ignby=?) AND nickname NOT IN (SELECT ignby FROM ' . PREFIX . 'ignored WHERE ign=?);');
$stmt->execute(array($_REQUEST['sendto'], $U['status'], $U['nickname'], $U['nickname']));
if($tmp=$stmt->fetch(PDO::FETCH_ASSOC)){
$P[$tmp['nickname']]=[$tmp['nickname'], $tmp['style'], $tmp['status'], $tmp['nickname']];
$inbox=true;
}
if(isSet($P[$_REQUEST['sendto']])){
$U['recipient']=$P[$_REQUEST['sendto']][0];
$U['displayrecp']=style_this($U['recipient'], $P[$_REQUEST['sendto']][1]);
$U['poststatus']='9';
$U['displaysend']=sprintf(get_setting('msgsendprv'), style_this($U['nickname'], $U['style']), $U['displayrecp']);
}
if(empty($U['recipient'])){// nick left already or ignores us
$U['message']='';
@ -2790,7 +2778,7 @@ function validate_input(){
$U['lastpost']=time();
$stmt=$db->prepare('UPDATE ' . PREFIX . 'sessions SET lastpost=?, postid=? WHERE session=?;');
$stmt->execute(array($U['lastpost'], $_REQUEST['postid'], $U['session']));
if(isSet($inboxes[$_REQUEST['sendto']])){
if($inbox){
$message=array(
'postdate' =>time(),
'poster' =>$U['nickname'],
@ -2829,11 +2817,11 @@ function apply_filter(){
}
read_members();
if(isSet($A[$matched[1]])){
return style_this($matched[0], $A[$matched[1]][2]);
return style_this($matched[0], $A[$matched[1]][1]);
}
foreach($A as $user){
if(strtolower($user[0])===$nick){
return style_this($matched[0], $user[2]);
return style_this($matched[0], $user[1]);
}
}
return "$matched[0]";
@ -2899,7 +2887,7 @@ function create_hotlinks(){
global $U;
//Make hotlinks for URLs, redirect through dereferrer script to prevent session leakage
// 1. all explicit schemes with whatever xxx://yyyyyyy
$U['message']=preg_replace('~(\w*://[^\s<>]+)~i', "<<$1>>", $U['message']);
$U['message']=preg_replace('~(\w+://[^\s<>]+)~i', "<<$1>>", $U['message']);
// 2. valid URLs without scheme:
$U['message']=preg_replace('~((?:[^\s<>]*:[^\s<>]*@)?[a-z0-9\-]+(?:\.[a-z0-9\-]+)+(?::\d*)?/[^\s<>]*)(?![^<>]*>)~i', "<<$1>>", $U['message']); // server/path given
$U['message']=preg_replace('~((?:[^\s<>]*:[^\s<>]*@)?[a-z0-9\-]+(?:\.[a-z0-9\-]+)+:\d+)(?![^<>]*>)~i', "<<$1>>", $U['message']); // server:port given
@ -2930,7 +2918,7 @@ function add_message(){
'poster' =>$U['nickname'],
'recipient' =>$U['recipient'],
'text' =>"<span class=\"usermsg\">$U[displaysend]".style_this($U['message'], $U['style']).'</span>',
'delstatus' =>$U['delstatus']
'delstatus' =>$U['status']
);
write_message($newmessage);
return true;
@ -2946,7 +2934,7 @@ function add_system_message($mes){
'poster' =>'',
'recipient' =>'',
'text' =>"<span class=\"sysmsg\">$mes</span>",
'delstatus' =>9
'delstatus' =>4
);
write_message($sysmessage);
}
@ -2961,8 +2949,8 @@ function write_message($message){
}
$stmt=$db->prepare('INSERT INTO ' . PREFIX . 'messages (postdate, poststatus, poster, recipient, text, delstatus) VALUES (?, ?, ?, ?, ?, ?);');
$stmt->execute(array($message['postdate'], $message['poststatus'], $message['poster'], $message['recipient'], $message['text'], $message['delstatus']));
$limit=get_setting('keeplimit')*get_setting('messagelimit');
$stmt=$db->query('SELECT id FROM ' . PREFIX . "messages ORDER BY id DESC LIMIT 1 OFFSET $limit");
$limit=get_setting('messagelimit');
$stmt=$db->query('SELECT id FROM ' . PREFIX . "messages WHERE poststatus=1 ORDER BY id DESC LIMIT 1 OFFSET $limit");
if($id=$stmt->fetch(PDO::FETCH_NUM)){
$stmt=$db->prepare('DELETE FROM ' . PREFIX . 'messages WHERE id<=?;');
$stmt->execute(array($id[0]));
@ -2982,12 +2970,12 @@ function clean_room(){
add_system_message(sprintf($msg, get_setting('chatname')));
}
function clean_selected(){
function clean_selected($status, $nick){
global $db;
if(isSet($_REQUEST['mid'])){
$stmt=$db->prepare('DELETE FROM ' . PREFIX . 'messages WHERE id=?;');
$stmt=$db->prepare('DELETE FROM ' . PREFIX . 'messages WHERE id=? AND (poster=? OR recipient=? OR (poststatus<? AND delstatus<?));');
foreach($_REQUEST['mid'] as $mid){
$stmt->execute(array($mid));
$stmt->execute(array($mid, $nick, $nick, $status, $status));
}
}
}
@ -3002,14 +2990,10 @@ function clean_inbox_selected(){
}
}
function del_all_messages($nick, $status, $entry){
global $U, $db;
if($nick===$U['nickname']) $status=10;
if($U['status']>1){
$entry=0;
}
$stmt=$db->prepare('DELETE FROM ' . PREFIX . 'messages WHERE poster=? AND delstatus<? AND postdate>?;');
$stmt->execute(array($nick, $status, $entry));
function del_all_messages($nick, $entry){
global $db;
$stmt=$db->prepare('DELETE FROM ' . PREFIX . 'messages WHERE poster=? AND postdate>?;');
$stmt->execute(array($nick, $entry));
$stmt=$db->prepare('DELETE FROM ' . PREFIX . 'inbox WHERE poster=?;');
$stmt->execute(array($nick));
}
@ -3035,7 +3019,6 @@ function print_messages($delstatus=''){
global $I, $U, $db;
$dateformat=get_setting('dateformat');
$tz=3600*$U['tz'];
$messagelimit=(int) get_setting('messagelimit');
if(!isSet($_COOKIE[COOKIENAME]) && get_setting('forceredirect')==0){
$injectRedirect=true;
$redirect=get_setting('redirect');
@ -3061,13 +3044,13 @@ function print_messages($delstatus=''){
send_fatal_error($I['opensslextrequired']);
}
}
$expire=time()-60*get_setting('messageexpire');
$db->exec('DELETE FROM ' . PREFIX . 'messages WHERE id IN (SELECT * FROM (SELECT id FROM ' . PREFIX . "messages WHERE postdate<$expire) AS t);");
$time=time();
$stmt=$db->prepare('DELETE FROM ' . PREFIX . 'messages WHERE id IN (SELECT * FROM (SELECT id FROM ' . PREFIX . 'messages WHERE postdate<(?-60*(SELECT value FROM ' . PREFIX . "settings WHERE setting='messageexpire'))) AS t);");
$stmt->execute([$time]);
if(!empty($delstatus)){
$stmt=$db->prepare('SELECT postdate, id, text FROM ' . PREFIX . 'messages WHERE '.
'id IN (SELECT * FROM (SELECT id FROM ' . PREFIX . "messages WHERE poststatus=1 ORDER BY id DESC LIMIT $messagelimit) AS t) ".
'OR (poststatus>1 AND (poststatus<? OR poster=? OR recipient=?) ) ORDER BY id DESC;');
$stmt->execute(array($U['status'], $U['nickname'], $U['nickname']));
'(poststatus<? AND delstatus<?) OR poster=? OR recipient=? ORDER BY id DESC;');
$stmt->execute(array($U['status'], $delstatus, $U['nickname'], $U['nickname']));
while($message=$stmt->fetch(PDO::FETCH_ASSOC)){
prepare_message_print($message, $injectRedirect, $redirect, $removeEmbed);
echo "<div class=\"msg\"><input type=\"checkbox\" name=\"mid[]\" id=\"$message[id]\" value=\"$message[id]\"><label for=\"$message[id]\">";
@ -3077,15 +3060,10 @@ function print_messages($delstatus=''){
echo " $message[text]</label></div>";
}
}else{
if(!isSet($_REQUEST['id'])){
$_REQUEST['id']=0;
}
$stmt=$db->prepare('SELECT id, postdate, text FROM ' . PREFIX . 'messages WHERE ('.
'id IN (SELECT * FROM (SELECT id FROM ' . PREFIX . "messages WHERE poststatus=1 ORDER BY id DESC LIMIT $messagelimit) AS t) ".
'OR (poststatus>1 AND poststatus<=?) '.
'OR (poststatus=9 AND ( (poster=? AND recipient NOT IN (SELECT ign FROM ' . PREFIX . 'ignored WHERE ignby=?) ) OR recipient=?) )'.
') AND poster NOT IN (SELECT ign FROM ' . PREFIX . 'ignored WHERE ignby=?) AND id>? ORDER BY id DESC;');
$stmt->execute(array($U['status'], $U['nickname'], $U['nickname'], $U['nickname'], $U['nickname'], $_REQUEST['id']));
$stmt=$db->prepare('SELECT id, postdate, text FROM ' . PREFIX . 'messages WHERE (poststatus<=? OR '.
'(poststatus=9 AND ( (poster=? AND recipient NOT IN (SELECT ign FROM ' . PREFIX . 'ignored WHERE ignby=?) ) OR recipient=?) )'.
') AND poster NOT IN (SELECT ign FROM ' . PREFIX . 'ignored WHERE ignby=?) ORDER BY id DESC;');
$stmt->execute(array($U['status'], $U['nickname'], $U['nickname'], $U['nickname'], $U['nickname']));
while($message=$stmt->fetch(PDO::FETCH_ASSOC)){
prepare_message_print($message, $injectRedirect, $redirect, $removeEmbed);
echo '<div class="msg">';
@ -3093,9 +3071,6 @@ function print_messages($delstatus=''){
echo '<small>'.date($dateformat, $message['postdate']+$tz).' - </small>';
}
echo "$message[text]</div>";
if($_REQUEST['id']<$message['id']){
$_REQUEST['id']=$message['id'];
}
}
}
}
@ -3122,6 +3097,14 @@ function prepare_message_print(&$message, $injectRedirect, $redirect, $removeEmb
// this and that
function sort_names(&$names){
$keys=[];
foreach($names as $v){
$keys[]=$v[3];
}
array_multisort(array_map('strtolower', $keys), SORT_ASC, SORT_STRING, $names);
}
function send_headers(){
header('Content-Type: text/html; charset=UTF-8');
header('Pragma: no-cache');
@ -3195,16 +3178,6 @@ function save_setup(){
}
}
function get_ignored(){
global $db;
$ignored=array();
$result=$db->query('SELECT ign, ignby FROM ' . PREFIX . 'ignored;');
while($tmp=$result->fetch(PDO::FETCH_ASSOC)){
$ignored[]=array('ignored'=>$tmp['ign'], 'by'=>$tmp['ignby']);
}
return $ignored;
}
function valid_admin(){
global $U;
if(isSet($_REQUEST['session'])){
@ -3247,11 +3220,12 @@ function print_colours(){
global $I;
// Prints a short list with selected named HTML colours and filters out illegible text colours for the given background.
// It's a simple comparison of weighted grey values. This is not very accurate but gets the job done well enough.
$colours=array('Beige'=>'F5F5DC', 'Black'=>'000000', 'Blue'=>'0000FF', 'BlueViolet'=>'8A2BE2', 'Brown'=>'A52A2A', 'Cyan'=>'00FFFF', 'DarkBlue'=>'00008B', 'DarkGreen'=>'006400', 'DarkRed'=>'8B0000', 'DarkViolet'=>'9400D3', 'DeepSkyBlue'=>'00BFFF', 'Gold'=>'FFD700', 'Grey'=>'808080', 'Green'=>'008000', 'HotPink'=>'FF69B4', 'Indigo'=>'4B0082', 'LightBlue'=>'ADD8E6', 'LightGreen'=>'90EE90', 'LimeGreen'=>'32CD32', 'Magenta'=>'FF00FF', 'Olive'=>'808000', 'Orange'=>'FFA500', 'OrangeRed'=>'FF4500', 'Purple'=>'800080', 'Red'=>'FF0000', 'RoyalBlue'=>'4169E1', 'SeaGreen'=>'2E8B57', 'Sienna'=>'A0522D', 'Silver'=>'C0C0C0', 'Tan'=>'D2B48C', 'Teal'=>'008080', 'Violet'=>'EE82EE', 'White'=>'FFFFFF', 'Yellow'=>'FFFF00', 'YellowGreen'=>'9ACD32');
// name=>[colour, greyval(colour)]
$colours=['Beige'=>['F5F5DC', 242.25], 'Black'=>['000000', 0], 'Blue'=>['0000FF', 28.05], 'BlueViolet'=>['8A2BE2', 91.63], 'Brown'=>['A52A2A', 78.9], 'Cyan'=>['00FFFF', 178.5], 'DarkBlue'=>['00008B', 15.29], 'DarkGreen'=>['006400', 59], 'DarkRed'=>['8B0000', 41.7], 'DarkViolet'=>['9400D3', 67.61], 'DeepSkyBlue'=>['00BFFF', 140.74], 'Gold'=>['FFD700', 203.35], 'Grey'=>['808080', 128], 'Green'=>['008000', 75.52], 'HotPink'=>['FF69B4', 158.25], 'Indigo'=>['4B0082', 36.8], 'LightBlue'=>['ADD8E6', 204.64], 'LightGreen'=>['90EE90', 199.46], 'LimeGreen'=>['32CD32', 141.45], 'Magenta'=>['FF00FF', 104.55], 'Olive'=>['808000', 113.92], 'Orange'=>['FFA500', 173.85], 'OrangeRed'=>['FF4500', 117.21], 'Purple'=>['800080', 52.48], 'Red'=>['FF0000', 76.5], 'RoyalBlue'=>['4169E1', 106.2], 'SeaGreen'=>['2E8B57', 105.38], 'Sienna'=>['A0522D', 101.33], 'Silver'=>['C0C0C0', 192], 'Tan'=>['D2B48C', 184.6], 'Teal'=>['008080', 89.6], 'Violet'=>['EE82EE', 174.28], 'White'=>['FFFFFF', 255], 'Yellow'=>['FFFF00', 226.95], 'YellowGreen'=>['9ACD32', 172.65]];
$greybg=greyval(get_setting('colbg'));
foreach($colours as $name=>$colour){
if(abs($greybg-greyval($colour))>75){
echo "<option value=\"$colour\" style=\"color:#$colour;\">$I[$name]</option>";
if(abs($greybg-$colour[1])>75){
echo "<option value=\"$colour[0]\" style=\"color:#$colour[0];\">$I[$name]</option>";
}
}
}
@ -3384,7 +3358,7 @@ function init_chat(){
$db->exec('CREATE INDEX ' . PREFIX . 'incognito ON ' . PREFIX . 'sessions(incognito);');
$db->exec('CREATE TABLE ' . PREFIX . "settings (setting varchar(50) NOT NULL PRIMARY KEY, value varchar(20000) NOT NULL);");
}
$settings=array(array('guestaccess', '0'), array('globalpass', ''), array('englobalpass', '0'), array('captcha', '0'), array('dateformat', 'm-d H:i:s'), array('rulestxt', ''), array('msgencrypted', '0'), array('dbversion', DBVERSION), array('css', 'a:visited{color:#B33CB4;} a:active{color:#FF0033;} a:link{color:#0000FF;} input,select,textarea{color:#FFFFFF;background-color:#000000;} a img{width:15%} a:hover img{width:35%} .error{color:#FF0033;} .delbutton{background-color:#660000;} .backbutton{background-color:#004400;} #exitbutton{background-color:#AA0000;} .center-table{margin-left:auto;margin-right:auto;} body{text-align:center;} .left-table{width:100%;text-align:left;} .right{text-align:right;} .left{text-align:left;} .right-table{border-spacing:0px;margin-left:auto;} .padded{padding:5px;} #chatters{max-height:100px;overflow-y:auto;} .center{text-align:center;}'), array('memberexpire', '60'), array('guestexpire', '15'), array('kickpenalty', '10'), array('entrywait', '120'), array('messageexpire', '14400'), array('messagelimit', '150'), array('maxmessage', 2000), array('captchatime', '600'), array('colbg', '000000'), array('coltxt', 'FFFFFF'), array('maxname', '20'), array('minpass', '5'), array('defaultrefresh', '20'), array('dismemcaptcha', '0'), array('suguests', '0'), array('imgembed', '1'), array('timestamps', '1'), array('trackip', '0'), array('captchachars', '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'), array('memkick', '1'), array('forceredirect', '0'), array('redirect', ''), array('incognito', '1'), array('chatname', 'My Chat'), array('topic', ''), array('msgsendall', $I['sendallmsg']), array('msgsendmem', $I['sendmemmsg']), array('msgsendmod', $I['sendmodmsg']), array('msgsendadm', $I['sendadmmsg']), array('msgsendprv', $I['sendprvmsg']), array('msgenter', $I['entermsg']), array('msgexit', $I['exitmsg']), array('msgmemreg', $I['memregmsg']), array('msgsureg', $I['suregmsg']), array('msgkick', $I['kickmsg']), array('msgmultikick', $I['multikickmsg']), array('msgallkick', $I['allkickmsg']), array('msgclean', $I['cleanmsg']), array('numnotes', '3'), array('keeplimit', '3'), array('mailsender', 'www-data <www-data@localhost>'), array('mailreceiver', 'Webmaster <webmaster@localhost>'), array('sendmail', '0'), array('modfallback', '1'), array('guestreg', '0'), array('disablepm', '0'), array('disabletext', "<h1>$I[disabledtext]</h1>"), array('defaulttz', '0'), array('eninbox', '0'));
$settings=array(array('guestaccess', '0'), array('globalpass', ''), array('englobalpass', '0'), array('captcha', '0'), array('dateformat', 'm-d H:i:s'), array('rulestxt', ''), array('msgencrypted', '0'), array('dbversion', DBVERSION), array('css', 'a:visited{color:#B33CB4;} a:active{color:#FF0033;} a:link{color:#0000FF;} input,select,textarea{color:#FFFFFF;background-color:#000000;} a img{width:15%} a:hover img{width:35%} .error{color:#FF0033;} .delbutton{background-color:#660000;} .backbutton{background-color:#004400;} #exitbutton{background-color:#AA0000;} .center-table{margin-left:auto;margin-right:auto;} body{text-align:center;} .left-table{width:100%;text-align:left;} .right{text-align:right;} .left{text-align:left;} .right-table{border-spacing:0px;margin-left:auto;} .padded{padding:5px;} #chatters{max-height:100px;overflow-y:auto;} .center{text-align:center;}'), array('memberexpire', '60'), array('guestexpire', '15'), array('kickpenalty', '10'), array('entrywait', '120'), array('messageexpire', '14400'), array('messagelimit', '150'), array('maxmessage', 2000), array('captchatime', '600'), array('colbg', '000000'), array('coltxt', 'FFFFFF'), array('maxname', '20'), array('minpass', '5'), array('defaultrefresh', '20'), array('dismemcaptcha', '0'), array('suguests', '0'), array('imgembed', '1'), array('timestamps', '1'), array('trackip', '0'), array('captchachars', '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'), array('memkick', '1'), array('forceredirect', '0'), array('redirect', ''), array('incognito', '1'), array('chatname', 'My Chat'), array('topic', ''), array('msgsendall', $I['sendallmsg']), array('msgsendmem', $I['sendmemmsg']), array('msgsendmod', $I['sendmodmsg']), array('msgsendadm', $I['sendadmmsg']), array('msgsendprv', $I['sendprvmsg']), array('msgenter', $I['entermsg']), array('msgexit', $I['exitmsg']), array('msgmemreg', $I['memregmsg']), array('msgsureg', $I['suregmsg']), array('msgkick', $I['kickmsg']), array('msgmultikick', $I['multikickmsg']), array('msgallkick', $I['allkickmsg']), array('msgclean', $I['cleanmsg']), array('numnotes', '3'), array('mailsender', 'www-data <www-data@localhost>'), array('mailreceiver', 'Webmaster <webmaster@localhost>'), array('sendmail', '0'), array('modfallback', '1'), array('guestreg', '0'), array('disablepm', '0'), array('disabletext', "<h1>$I[disabledtext]</h1>"), array('defaulttz', '0'), array('eninbox', '0'));
$stmt=$db->prepare('INSERT INTO ' . PREFIX . 'settings (setting, value) VALUES (?, ?);');
foreach($settings as $pair){
$stmt->execute($pair);
@ -3518,7 +3492,7 @@ function update_db(){
}
}
if($dbversion<15){
$db->exec('INSERT INTO ' . PREFIX . "settings (setting, value) VALUES ('keeplimit', '3'), ('mailsender', 'www-data <www-data@localhost>'), ('mailreceiver', 'Webmaster <webmaster@localhost>'), ('sendmail', '0'), ('modfallback', '1'), ('guestreg', '0');");
$db->exec('INSERT INTO ' . PREFIX . "settings (setting, value) VALUES ('mailsender', 'www-data <www-data@localhost>'), ('mailreceiver', 'Webmaster <webmaster@localhost>'), ('sendmail', '0'), ('modfallback', '1'), ('guestreg', '0');");
}
if($dbversion<16){
$css=get_setting('css');
@ -3562,6 +3536,12 @@ function update_db(){
$memcached->delete(DBNAME . '-' . PREFIX . "settings-enablejs");
}
}
if($dbversion<24){
$db->exec('DELETE FROM ' . PREFIX . 'ignored WHERE id IN (SELECT id FROM (SELECT ' . PREFIX . 'ignored.id, ign, ignby FROM ' . PREFIX . 'ignored, ' . PREFIX . 'members WHERE nickname=ignby AND status < (SELECT status FROM ' . PREFIX . 'members WHERE nickname=ign) ) AS t);');
}
if($dbversion<25){
$db->exec('DELETE FROM ' . PREFIX . "settings WHERE setting='keeplimit';");
}
update_setting('dbversion', DBVERSION);
if(get_setting('msgencrypted')!=MSGENCRYPTED){
if(!extension_loaded('openssl')){
@ -3750,8 +3730,8 @@ function load_lang(){
function load_config(){
date_default_timezone_set('UTC');
define('VERSION', '1.20.3'); // Script version
define('DBVERSION', 23); // Database version
define('VERSION', '1.20.6'); // Script version
define('DBVERSION', 25); // Database version
define('MSGENCRYPTED', false); // Store messages encrypted in the database to prevent other database users from reading them - true/false - visit the setup page after editing!
define('ENCRYPTKEY', 'MY_KEY'); // Encryption key for messages
define('DBHOST', 'localhost'); // Database host

View File

@ -254,7 +254,6 @@ $T=array(
'captchatime' => 'Captcha-Ablaufzeit (Sekunden)',
'messageexpire' => 'Nachrichten-Ablaufzeit (Minuten)',
'messagelimit' => 'Nachrichtenlimit (öffentliche)',
'keeplimit' => 'So viele Male zusätzliche Nachrichten behalten (PMs und Mitgliederchat)',
'maxmessage' => 'Maximale Nachrichenlänge',
'confirm' => 'Bist du sicher?',
'yes' => 'Ja',

View File

@ -254,7 +254,6 @@ $I=array(
'captchatime' => 'Captcha timeout (seconds)',
'messageexpire' => 'Message timeout (minutes)',
'messagelimit' => 'Message limit (public)',
'keeplimit' => 'Keep this times additional messages (PMs and Member chat)',
'maxmessage' => 'Maximal message length',
'confirm' => 'Are you sure?',
'yes' => 'Yes',