With this changes another admin wont be able to take the admin flag from you, ban you or kick you..
All you need to do is create a new array parameter at the index.php or chat script you are using.
You can put as many nicknames you want in this array and all of them will be protected from the above commands, nicknames that aren't in this array will be unprotected from banning, kicking or deop from another admin..
You can use the parameter like so:
- Code: Select all
$params['portectedAdmins'] = array('admin1','admin2');
Where admin1 and admin2 you want to protect, it can be only one if you like.. not using this parameter wont do harm to the chat itself, so you can also not use it..
now lets proceed to the changes for phpfreechat 1.3.
Update : 10/10/2011
There was the possibility if you don't have a registration system and a guest user use your protected nickname "impersonate you" (admin nickname), wouldn't be possible for a real admin to kick and ban the impersonator while in the chat session.
If you don't want to read further here is the download link
http://vcomputadoras.com/phpfreechat1_3protectA.rar
copy paste this on src/pfcglobalconfig.class.php
- Code: Select all
/**
* <p>Add protected admins that you want to protect from others admin from taking
* the admin flag, ban or Kick. Utan aka re*s.t.a.r.s.*2.
* (Default value: an empty array)</p>
*/
var $portectedAdmins = array();
copy paste this on src/phpfreechat.class.php
- Code: Select all
<?php
/**
* phpfreechat.class.php
*
* Copyright © 2006 Stephane Gully <stephane.gully@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
* New additions by Neumann valle AKA utan, re*s.t.a.r.s.*2
* added $protectedAdmin Parameter.
* vcomputadoras@yahoo.com
*/
require_once dirname(__FILE__).'/pfccommand.class.php';
require_once dirname(__FILE__).'/pfcglobalconfig.class.php';
require_once dirname(__FILE__).'/pfcuserconfig.class.php';
require_once dirname(__FILE__).'/pfctemplate.class.php';
require_once dirname(__FILE__).'/../lib/utf8/utf8_substr.php';
require_once dirname(__FILE__).'/pfcresponse.class.php';
/**
* phpFreeChat is the entry point for developpers
*
* @example ../demo/demo1_simple.php
* @author Stephane Gully <stephane.gully@gmail.com>
*/
class phpFreeChat
{
function phpFreeChat( &$params )
{
if (!is_array($params))
die('phpFreeChat parameters must be an array');
// initialize the global config object
$c =& pfcGlobalConfig::Instance( $params );
// need to initiate the user config object here because it uses sessions
$u =& pfcUserConfig::Instance();
// this code is used to handle the AJAX call and build the response
if (isset($_REQUEST['pfc_ajax']))
{
$function = isset($_REQUEST['f']) ? $_REQUEST['f'] : '';
$cmd = isset($_REQUEST['cmd']) ? stripslashes($_REQUEST['cmd']) : '';
$r = null;
if ($function && method_exists($this,$function))
{
require_once dirname(__FILE__).'/pfcresponse.class.php';
$r =& $this->$function($cmd);
}
echo $r->getOutput();
die();
}
}
/**
* depreciated
*/
function printJavaScript( $return = false )
{
$output = '';
if ($return)
return $output;
else
echo $output;
}
/**
* depreciated
*/
function printStyle( $return = false )
{
$output = '';
if($return)
return $output;
else
echo $output;
}
/**
* printChat must be called somewhere in the page
* it inserts necessary html which will receive chat's data
* usage:
* <code>
* <?php $chat->printChat(); ?>
* </code>
*/
function printChat( $return = false )
{
$c =& pfcGlobalConfig::Instance();
$u =& pfcUserConfig::Instance();
$output = '';
if (count($c->getErrors()) > 0)
{
$output .= "<p>phpFreeChat cannot be initialized, please correct these errors:</p><ul>";
foreach( $c->getErrors() as $e ) $output .= "<li>".$e."</li>"; $output .= "</ul>";
}
else
{
pfcI18N::SwitchOutputEncoding($c->output_encoding);
$path = $c->getFilePathFromTheme('chat.js.tpl.php');
$t = new pfcTemplate($path);
$t->assignObject($u,"u");
$t->assignObject($c,"c");
$output .= $t->getOutput();
pfcI18N::SwitchOutputEncoding();
}
if($return)
return $output;
else
echo $output;
}
/**
* Encode special caracteres and remove extra slashes
*/
function FilterSpecialChar($str)
{
return htmlspecialchars($str, ENT_NOQUOTES);
}
/**
* Just check the nicknames doesn't start with spaces and is not longer than the max_nick_len
*/
function FilterNickname($nickname)
{
$c =& pfcGlobalConfig::Instance();
//$nickname = str_replace("\", "", $nickname); // '' is a forbidden charactere for nicknames
$nickname = trim($nickname);
$nickname = utf8_substr($nickname, 0, $c->max_nick_len);
return $nickname;
}
/**
* search/replace smileys
*/
function FilterSmiley($msg)
{
$c =& pfcGlobalConfig::Instance();
// build a preg_replace array
$search = array();
$replace = array();
$query = "/(";
foreach($c->smileys as $s_file => $s_strs)
{
foreach ($s_strs as $s_str)
{
$s_str = stripslashes($s_str); /* the :'( smileys needs this filter */
$query .= preg_quote($s_str,'/')."|";
$search[] = "/".preg_quote($s_str,'/')."/";
$replace[] = '<img src="'.$s_file.'" alt="'.$s_str.'" title="'.$s_str.'" />';
}
}
$query = substr($query, 0, strlen($query)-1);
$query .= ")/i";
$split_words = preg_split($query, $msg, -1, PREG_SPLIT_DELIM_CAPTURE);
$msg = "";
foreach($split_words as $word)
$msg .= preg_replace($search, $replace, $word);
return $msg;
}
/**
* Filter messages before they are sent to container
*/
function PreFilterMsg($msg)
{
$c =& pfcGlobalConfig::Instance();
if (preg_match("/^[/i",$msg))
// add 25 characteres if the message starts with [ : means there is a bbcode
$msg = utf8_substr($msg, 0, $c->max_text_len+25);
else
$msg = utf8_substr($msg, 0, $c->max_text_len);
$msg = phpFreeChat::FilterSpecialChar($msg);
// $msg = phpFreeChat::FilterSmiley($msg);
/* if ($msg[0] == "n") $msg = substr($msg, 1); */ // delete the first n generated by FF
/* if (strpos($msg,"n") > 0) $msg = "<br/>".$msg;
$msg = str_replace("rn", "<br/>", $msg);
$msg = str_replace("n", "<br/>", $msg);
$msg = str_replace("t", " ", $msg);*/
//$msg = str_replace(" ", " ", $msg);
// $msg = preg_replace('/(http://[^s]*)/i', "<a href="$1">$1</a>", $msg );
return $msg;
}
/**
* Filter messages when they are recived from container
*/
function PostFilterMsg($msg)
{
//$c =& pfcGlobalConfig::Instance();
// $msg = preg_replace('/('.preg_quote($c->nick,'/').')/i', "<strong>$1</strong>", $msg );
$msg = preg_replace('/n/i', "", $msg );
return $msg;
}
function &handleRequest($request)
{
$c =& pfcGlobalConfig::Instance();
$u =& pfcUserConfig::Instance();
if ($c->debug) ob_start(); // capture output
$xml_reponse = new pfcResponse();
// check the command
$cmdstr = "";
$cmdname = "";
$clientid = "";
$recipient = "";
$recipientid = "";
$param = "";
$sender = "";
$res = pfcCommand::ParseCommand($request);
$cmdstr = isset($res['cmdstr']) ? $res['cmdstr'] : $request;
$cmdname = strtolower(isset($res['cmdname']) ? $res['cmdname'] : '');
$clientid = isset($res['params'][0]) ? $res['params'][0] : '';
$recipientid = isset($res['params'][1]) ? $res['params'][1] : "";
$params = array_slice(is_array($res['params']) ? $res['params'] : array() ,2);
$param = implode(" ",$params); // to keep compatibility (will be removed)
$sender = $u->getNickname();
// translate the recipientid to the channel name
if (isset($u->channels[$recipientid]))
{
$recipient = $u->channels[$recipientid]["recipient"];
}
if (isset($u->privmsg[$recipientid]))
{
$recipient = $u->privmsg[$recipientid]["recipient"];
// @todo: move this code in a proxy
if ($cmdname != "update" &&
$cmdname != "leave" && // do not open the pv tab when other user close the tab
$cmdname != "quit" &&
$cmdname != "privmsg2")
{
// alert the other from the new pv
// (warn other user that someone talk to him)
$ct =& pfcContainer::Instance();
$nickidtopv = $u->privmsg[$recipientid]["pvnickid"];
$cmdstr = 'privmsg2';
$cmdp = array();
$cmdp['param'] = $u->nickid;//$sender;
$cmdp['params'][] = $u->nickid;//$sender;
pfcCommand::AppendCmdToPlay($nickidtopv, $cmdstr, $cmdp);
}
}
$cmdp = array();
$cmdp["clientid"] = $clientid;
$cmdp["sender"] = $sender;
$cmdp["recipient"] = $recipient;
$cmdp["recipientid"] = $recipientid;
// before playing the wanted command
// play the found commands into the meta 'cmdtoplay'
pfcCommand::RunPendingCmdToPlay($u->nickid, $cmdp, $xml_reponse);
// play the wanted command
$cmd =& pfcCommand::Factory($cmdname);
$cmdp["param"] = $param;
$cmdp["params"] = $params;
if ($cmd != NULL)
{
// call the command
if ($c->debug)
$cmd->run($xml_reponse, $cmdp);
else
@$cmd->run($xml_reponse, $cmdp);
}
else
{
$cmd =& pfcCommand::Factory("error");
$cmdp = array();
$cmdp["clientid"] = $clientid;
$cmdp["param"] = _pfc("Unknown command [%s]",stripslashes("/".$cmdname." ".$param));
$cmdp["sender"] = $sender;
$cmdp["recipient"] = $recipient;
$cmdp["recipientid"] = $recipientid;
if ($c->debug)
$cmd->run($xml_reponse, $cmdp);
else
@$cmd->run($xml_reponse, $cmdp);
}
// do not update twice
// do not update when the user just quit
if ($cmdname != "update" &&
$cmdname != "quit" &&
$u->nickid != '')
{
// force an update just after a command is sent
// thus the message user just poster is really fastly displayed
$cmd =& pfcCommand::Factory("update");
$cmdp = array();
$cmdp["clientid"] = $clientid;
$cmdp["param"] = $param;
$cmdp["sender"] = $sender;
$cmdp["recipient"] = $recipient;
$cmdp["recipientid"] = $recipientid;
if ($c->debug)
$cmd->run($xml_reponse, $cmdp);
else
@$cmd->run($xml_reponse, $cmdp);
}
if ($c->debug)
{
// capture echoed content
// if a content not empty is captured it is a php error in the code
$data = ob_get_contents();
if ($data != "")
{
// todo : display the $data somewhere to warn the user
}
ob_end_clean();
}
// do nothing else if the xml response is empty in order to save bandwidth
if ($xml_reponse->getCommandCount() == 0) die();
return $xml_reponse;
}
function &loadStyles($theme = 'default', &$xml_reponse)
{
if ($xml_reponse == null) $xml_reponse = new pfcResponse();
$c =& pfcGlobalConfig::Instance();
// do not overload the theme parameter as long as
// the ajax request do not give the correct one
// $c->theme = $theme;
$u =& pfcUserConfig::Instance();
$js = '';//file_get_contents(dirname(__FILE__).'/client/createstylerule.js');
$js .= 'var c = $H();';
$path = $c->getFilePathFromTheme('style.css.php');
require_once dirname(__FILE__).'/../lib/ctype/ctype.php'; // to keep compatibility for php without ctype support
require_once dirname(__FILE__).'/../lib/csstidy-1.2/class.csstidy.php';
$css = new csstidy();
$css->set_cfg('preserve_css',false);
$css_code = '';
$t = new pfcTemplate();
$t->assignObject($u,"u");
$t->assignObject($c,"c");
if (!$c->isDefaultFile('style.css.php'))
{
$t->setTemplate($c->theme_default_path.'/default/style.css.php');
$css_code .= $t->getOutput();
}
$t->setTemplate($c->getFilePathFromTheme('style.css.php'));
$css_code .= $t->getOutput();
$css->parse($css_code);
foreach($css->css as $k => $v)
{
foreach($v as $k2 => $v2)
{
$rules = '';
foreach($v2 as $k3 => $v3)
$rules .= $k3.':'.$v3.';';
$js .= "c.set('".$k2."', '".str_replace("n", "", $rules)."');n";
}
}
$js .= "var pfccss = new pfcCSS(); var k = c.keys(); c.each(function (a) { pfccss.applyRule(a[0],a[1]); });";
$xml_reponse->script($js);
return $xml_reponse;
}
function &loadScripts($theme, &$xml_reponse)
{
if ($xml_reponse == null) $xml_reponse = new pfcResponse();
$c =& pfcGlobalConfig::Instance();
$js = '';
// load customize.js.php
$path = $c->getFilePathFromTheme('customize.js.php');
$t = new pfcTemplate($path);
$t->assignObject($c,"c");
$js .= $t->getOutput();
// load translations
require_once dirname(__FILE__).'/pfcjson.class.php';
$json = new pfcJSON();
$labels_to_load =
array( "Do you really want to leave this room ?", // _pfc
"Are you sure you want to close this tab ?", // _pfc
"Hide nickname marker", // _pfc
"Show nickname marker", // _pfc
"Hide dates and hours", // _pfc
"Show dates and hours", // _pfc
"Disconnect", // _pfc
"Connect", // _pfc
"Magnify", // _pfc
"Cut down", // _pfc
"Hide smiley box", // _pfc
"Show smiley box", // _pfc
"Hide online users box", // _pfc
"Show online users box", // _pfc
"Please enter your nickname", // _pfc
"Private message", // _pfc
"Close this tab", // _pfc
"Enter your message here", // _pfc
"Enter your nickname here", // _pfc
"Bold", // _pfc
"Italics", // _pfc
"Underline", // _pfc
"Delete", // _pfc
"Mail", // _pfc
"Color", // _pfc
"PHP FREE CHAT [powered by phpFreeChat-%s]", // _pfc
"Enter the text to format", // _pfc
"Configuration has been rehashed", // _pfc
"A problem occurs during rehash", // _pfc
"Chosen nickname is already used", // _pfc
"phpfreechat current version is %s", // _pfc
"Maximum number of joined channels has been reached", // _pfc
"Maximum number of private chat has been reached", // _pfc
"Click here to send your message", // _pfc
"Send", // _pfc
"You are not allowed to speak to yourself", // _pfc
"Close", // _pfc
"Chosen nickname is not allowed", // _pfc
"Enable sound notifications", // _pfc
"You cant deop %s is a protected admin..", // _pfc
"Unable to ban %s is a protected admin..", // _pfc
"Unable to kick %s is a protected admin..", // _pfc
"Disable sound notifications", // _pfc
"Input Required", // _pfc
"OK", // _pfc
"Cancel", // _pfc
"You are trying to speak to a unknown (or not connected) user", // _pfc
);
foreach($labels_to_load as $l)
{
$js .= "pfc.res.setLabel(".$json->encode($l).",".$json->encode(_pfc2($l)).");n";
}
// load ressources
$fileurl_to_load =
array( 'images/ch.gif',
'images/pv.gif',
'images/tab_remove.gif',
'images/ch-active.gif',
'images/pv-active.gif',
'images/user.gif',
'images/user-me.gif',
'images/user_female.gif',
'images/user_female-me.gif',
'images/color-on.gif',
'images/color-off.gif',
'images/clock-on.gif',
'images/clock-off.gif',
'images/logout.gif',
'images/login.gif',
'images/maximize.gif',
'images/minimize.gif',
'images/smiley-on.gif',
'images/smiley-off.gif',
'images/online-on.gif',
'images/online-off.gif',
'images/bt_strong.gif',
'images/bt_em.gif',
'images/bt_ins.gif',
'images/bt_del.gif',
'images/bt_mail.gif',
'images/bt_color.gif',
'images/color_transparent.gif',
'images/close-whoisbox.gif',
'images/openpv.gif',
'images/user-admin.gif',
'images/sound-on.gif',
'images/sound-off.gif',
'sound.swf',
);
foreach($fileurl_to_load as $f)
{
$js .= "pfc.res.setFileUrl(".$json->encode($f).","".$c->getFileUrlFromTheme($f)."");n";
}
foreach($c->smileys as $s_file => $s_str) {
for($j = 0; $j<count($s_str) ; $j++) {
$js .= "pfc.res.setSmiley(".$json->encode($s_str[$j]).","".$c->getFileUrlFromTheme($s_file)."");n";
}
}
$js .= '
pfc.gui.loadSmileyBox();
pfc.gui.loadBBCodeColorList();
pfc.connectListener();
pfc.refreshGUI();
if (pfc_connect_at_startup) pfc.connect_disconnect();
';
$xml_reponse->script($js);
return $xml_reponse;
}
function loadInterface($theme = 'default', &$xml_reponse)
{
if ($xml_reponse == null) $xml_reponse = new pfcResponse();
$c =& pfcGlobalConfig::Instance();
// do not overload the theme parameter as long as
// the ajax request do not give the correct one
// $c->theme = $theme;
$u =& pfcUserConfig::Instance();
$html = '';
// pfcI18N::SwitchOutputEncoding($c->output_encoding);
$path = $c->getFilePathFromTheme('chat.html.tpl.php');
$t = new pfcTemplate($path);
$t->assignObject($u,"u");
$t->assignObject($c,"c");
$html .= $t->getOutput();
// pfcI18N::SwitchOutputEncoding();
$xml_reponse->remove('pfc_loader'); // to hide the loading box
$xml_reponse->update('pfc_container', $html);
return $xml_reponse;
}
function &loadChat($theme = 'default')
{
$xml_reponse = new pfcResponse();
$this->loadInterface($theme,$xml_reponse);
$this->loadStyles($theme,$xml_reponse);
$this->loadScripts($theme,$xml_reponse);
return $xml_reponse;
}
}
?>
copy paste this on src/commands/ban.class.php
- Code: Select all
<?php
/*
* 10/09/2011
* New additions by Neumann valle AKA utan, re*s.t.a.r.s.*2
* added protected admin from ban.. by other admins
* vcomputadoras@yahoo.com
*/
require_once(dirname(__FILE__)."/../pfccommand.class.php");
class pfcCommand_ban extends pfcCommand
{
var $usage = "/ban {nickname} [ {reason} ]";
function run(&$xml_reponse, $p)
{
$clientid = $p["clientid"];
$param = $p["param"];
$params = $p["params"];
$sender = $p["sender"];
$recipient = $p["recipient"];
$recipientid = $p["recipientid"];
$c =& pfcGlobalConfig::Instance();
$u =& pfcUserConfig::Instance();
$ct =& pfcContainer::Instance();
$nick = isset($params[0]) ? $params[0] : '';
$reason = isset($params[1]) ? $params[1] : '';
$isadmin = $ct->getUserMeta($ct->getNickId($nick),'isadmin') ? true : false;
if ($reason == '') $reason = _pfc("no reason");
// to allow unquotted reason
if (count($params) > 2)
for ($x=2;$x<count($params);$x++)
$reason.=" ".$params[$x];
$channame = $u->channels[$recipientid]["name"];
if ($nick == '')
{
// error
$cmdp = $p;
$cmdp["param"] = _pfc("Missing parameter");
$cmdp["param"] .= " (".$this->usage.")";
$cmd =& pfcCommand::Factory("error");
$cmd->run($xml_reponse, $cmdp);
return;
}
if (in_array($nick, $c->portectedAdmins) && $isadmin )
{
// error
$cmdp = $p;
$cmdp["param"] = _pfc("Unable to ban %s is a protected admin..", $nick);
$cmd =& pfcCommand::Factory("error");
$cmd->run($xml_reponse, $cmdp);
return;
}
$ct =& pfcContainer::Instance();
$nickidtoban = $ct->getNickId($nick);
// notify all the channel
$cmdp = $p;
$cmdp["param"] = _pfc("%s banished from %s by %s", $nick, $channame, $sender);
$cmdp["flag"] = 4;
$cmd =& pfcCommand::Factory("notice");
$cmd->run($xml_reponse, $cmdp);
// kick the user (maybe in the future, it will exists a /kickban command)
$cmdp = $p;
$cmdp["params"] = array();
$cmdp["params"][] = $nick; // nickname to kick
$cmdp["params"][] = $reason; // reason
$cmd =& pfcCommand::Factory("kick");
$cmd->run($xml_reponse, $cmdp);
// update the recipient banlist
$banlist = $ct->getChanMeta($recipient, 'banlist_nickid');
if ($banlist == NULL)
$banlist = array();
else
$banlist = unserialize($banlist);
$banlist[] = $nickidtoban; // append the nickid to the banlist
$ct->setChanMeta($recipient, 'banlist_nickid', serialize($banlist));
}
}
?>
copy paste this on src/commands/kick.class.php
- Code: Select all
<?php
/*
* 10/09/2011
* New additions by Neumann valle AKA utan, re*s.t.a.r.s.*2
* added protected admin from kick.. by other admins
* vcomputadoras@yahoo.com
*/
require_once(dirname(__FILE__)."/../pfccommand.class.php");
class pfcCommand_kick extends pfcCommand
{
var $usage = "/kick {nickname} [ {reason} ]";
function run(&$xml_reponse, $p)
{
$clientid = $p["clientid"];
$param = $p["param"];
$params = $p["params"];
$sender = $p["sender"];
$recipient = $p["recipient"];
$recipientid = $p["recipientid"];
$c =& pfcGlobalConfig::Instance();
$u =& pfcUserConfig::Instance();
$ct =& pfcContainer::Instance();
$nick = isset($params[0]) ? $params[0] : '';
$reason = isset($params[1]) ? $params[1] : '';
$isadmin = $ct->getUserMeta($ct->getNickId($nick),'isadmin') ? true : false;
if ($reason == '') $reason = _pfc("no reason");
// to allow unquotted reason
if (count($params) > 2)
for ($x=2;$x<count($params);$x++)
$reason.=" ".$params[$x];
if ($nick == '')
{
// error
$cmdp = $p;
$cmdp["param"] = _pfc("Missing parameter");
$cmdp["param"] .= " (".$this->usage.")";
$cmd =& pfcCommand::Factory("error");
$cmd->run($xml_reponse, $cmdp);
return;
}
if (in_array($nick, $c->portectedAdmins) && $isadmin )
{
// error
$cmdp = $p;
$cmdp["param"] = _pfc("Unable to kick %s is a protected admin..", $nick);
$cmd =& pfcCommand::Factory("error");
$cmd->run($xml_reponse, $cmdp);
return;
}
// kicking a user just add a command to play to the aimed user metadata.
$ct =& pfcContainer::Instance();
$otherid = $ct->getNickId($nick);
$channame = $u->channels[$recipientid]["name"];
$cmdstr = 'leave';
$cmdp = array();
$cmdp['flag'] = 4;
$cmdp['params'][] = 'ch';
$cmdp['params'][] = $channame; // channel name
$cmdp['params'][] = _pfc("kicked from %s by %s - reason: %s", $channame, $sender, $reason); // reason
pfcCommand::AppendCmdToPlay($otherid, $cmdstr, $cmdp);
}
}
?>
copy paste this on i18n/en_US/main.php
- Code: Select all
// line 32 in deop.class.php
$GLOBALS["i18n"]["You cant deop %s is a protected admin.."] = "You cant deop %s is a protected admin..";
// line 46 in ban.class.php
$GLOBALS["i18n"]["Unable to ban %s is a protected admin.."] = "Unable to ban %s is a protected admin..";
// line 44 in kick.class.php
$GLOBALS["i18n"]["Unable to kick %s is a protected admin.."] = "Unable to kick %s is a protected admin..";
Hope this is helpful,
regards.