Advertisement
Guest User

Pixmicat! mod_adminenhance special edition for 6th&oldest

a guest
Mar 5th, 2013
156
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <?php
  2. class mod_adminenhance{
  3.         var $mypage;
  4.         var $ipfile, $imgfile, $wordfile;
  5.  
  6.         function mod_adminenhance($PMS){
  7.                 $PMS->hookModuleMethod('ModulePage', __CLASS__);
  8.                 $this->mypage = $PMS->getModulePageURL(__CLASS__);
  9.                 $this->ipfile = '.ht_blacklist';
  10.         $this->imgfile = '.ht_md5list';
  11.                 $this->wordfile = '.ht_wordlist';
  12.         }
  13.  
  14.         function getModuleName(){
  15.                 return 'mod_adminenhance : 管理工具增強組合包+自改 by dbfox';
  16.         }
  17.  
  18.         function getModuleVersionInfo(){
  19.                 return '5th.Release.Fin(v100318) - 整合mod_siokara強制sage功能(100626)+擋字功能(120819)';
  20.         }
  21.  
  22.         /* 從資料檔抓出資料 */
  23.         function _parseBlackListFile($fname, $only1st=false){
  24.                 if(!is_file($fname)) return array();
  25.                 $l = file($fname);
  26.                 $r = array(); $autodelno = array();
  27.                 $tmp = '';
  28.                 $now = time();
  29.                 for($i = 0, $len = count($l); $i < $len; $i++){
  30.                         $tmp = explode("\t", rtrim($l[$i]));
  31.                         if(isset($tmp[3]) && $tmp[3] != '0'){ // 封鎖時段已過
  32.                                 if($tmp[2] + intval($tmp[3]) * 86400 < $now){
  33.                                         $autodelno[] = $i;
  34.                                         continue;
  35.                                 }
  36.                         }
  37.                         $r[] = $only1st ? $tmp[0] : $tmp;
  38.                 }
  39.                 if(count($autodelno)) $this->_arrangeRecord($this->ipfile, $autodelno, ''); // 進行清除動作
  40.                 return $r;
  41.         }
  42.  
  43.         /* 重新整理記錄檔內容 (同步進行刪除及新增動作) */
  44.         function _arrangeRecord($fname, $arrDel, $newline){
  45.                 $line = is_file($fname) ? file($fname) : array();
  46.                 if(is_array($arrDel)) foreach($arrDel as $delid) unset($line[$delid]); // 刪除
  47.                 $line = implode('', $line).$newline;
  48.                 $fp = fopen($fname, 'w');
  49.                 fwrite($fp, $line);
  50.                 fclose($fp);
  51.         }
  52.  
  53.         /* 在前端管理顯示 Hostname */
  54.         function _showHostString(&$arrLabels, $post, $isReply){
  55.                 $arrLabels['{$NOW}'] .= " <u>{$post['host']}</u>";
  56.         }
  57.  
  58.         /* 封鎖黑名單管理頁面插入CSS & JS */
  59.         function _hookHeadCSS(&$style, $isReply){
  60.                 $style .= '<style type="text/css">
  61. .dos_list_short {
  62.        height: 150px;
  63.        width: 800px;
  64.        overflow: auto;
  65.        background: #e9f5ff;
  66.        border: 1px solid #666;
  67. }
  68. </style>
  69. <script type="text/javascript">
  70. // <![CDATA[
  71. function add(form){
  72.        var op = form.operate.value, ndata = form.newdata.value, nperiod = form.newperiod.value, ndesc = form.newdesc.value;
  73.        $.post("'.str_replace('&amp;', '&', $this->mypage).'", {operate: op, newdata: ndata, newperiod: nperiod, newdesc: ndesc, ajax: true}, function(d){
  74.                var l, lastno = (l = $("input:checkbox:last", form).get(0)) ? parseInt(l.value) + 1 : 0;
  75.                $("table", form).append(d.replace("#NO#", lastno));
  76.                form.newdata.value = form.newdesc.value = "";
  77.        });
  78.        return false;
  79. }
  80. // ]]>
  81. </script>
  82. ';
  83.         }
  84.  
  85.         function autoHookRegistBegin(){
  86.                 global $BANPATTERN, $BAD_FILEMD5, $BAD_STRING;
  87.                 // 載入封鎖黑名單定義檔
  88.                 if(is_file($this->ipfile)) $BANPATTERN = array_merge($BANPATTERN, array_map('rtrim', $this->_parseBlackListFile($this->ipfile, true)));
  89.                 if(is_file($this->imgfile)) $BAD_FILEMD5 = array_merge($BAD_FILEMD5, array_map('rtrim', $this->_parseBlackListFile($this->imgfile, true)));
  90.                 if(is_file($this->wordfile)) $BAD_STRING = array_merge($BAD_STRING, array_map('rtrim', $this->_parseBlackListFile($this->wordfile, true)));
  91.         }
  92.  
  93.         function autoHookAdminFunction($action, &$param, $funcLabel, &$message){
  94.                 global $PIO, $PMS;
  95.                 if($action=='add'){
  96.                         // Manual hook: showing hostname of users
  97.                         $PMS->hookModuleMethod('ThreadPost', array(&$this, '_showHostString'));
  98.                         $PMS->hookModuleMethod('ThreadReply', array(&$this, '_showHostString'));
  99.  
  100.                         $param[] = array('mod_adminenhance_thstop', 'AE: 停止/恢復討論串');
  101.                         $param[] = array('mod_adminenhance_thsage', 'AE: 強制SAGE/恢復討論串');
  102.                         $param[] = array('mod_adminenhance_banip', 'AE: IP 加到黑名單 (鎖 Class C)');
  103.                         $param[] = array('mod_adminenhance_banimg', 'AE: 圖檔 MD5 加到黑名單');
  104.                         return;
  105.                 }
  106.  
  107.                 switch($funcLabel){
  108.                         case 'mod_adminenhance_thstop':
  109.                                 $infectThreads = array();
  110.                                 foreach($PIO->fetchPosts($param) as $th){
  111.                                         if($th['resto']) continue; // 是回應
  112.                                         $infectThreads[] = $th['no'];
  113.                                         $flgh = $PIO->getPostStatus($th['status']);
  114.                                         $flgh->toggle('TS');
  115.                                         $PIO->setPostStatus($th['no'], $flgh->toString());
  116.                                 }
  117.                                 $PIO->dbCommit();
  118.                                 $message .= '停止/恢復討論串 (No.'.implode(', ', $infectThreads).') 完成<br />';
  119.                                 break;
  120.                         case 'mod_adminenhance_thsage':
  121.                                 $infectThreads = array();
  122.                                 foreach($PIO->fetchPosts($param) as $th){
  123.                                         if($th['resto']) continue; // 是回應
  124.                                         $infectThreads[] = $th['no'];
  125.                                         $flgh = $PIO->getPostStatus($th['status']);
  126.                                         $flgh->toggle('asage');
  127.                                         $PIO->setPostStatus($th['no'], $flgh->toString());
  128.                                 }
  129.                                 $PIO->dbCommit();
  130.                                 $message .= '強制SAGE/恢復討論串 (No.'.implode(', ', $infectThreads).') 完成<br />';
  131.                                 break;
  132.                         case 'mod_adminenhance_banip':
  133.                                 $fp = fopen($this->ipfile, 'a');
  134.                                 foreach($PIO->fetchPosts($param) as $th){
  135.                                         if(($IPaddr = gethostbyname($th['host'])) != $th['host']) $IPaddr .= '/24';
  136.                                         fwrite($fp, $IPaddr."\t\t".time()."\t0\n");
  137.                                 }
  138.                                 fclose($fp);
  139.                                 $message .= 'IP 黑名單更新完成<br />';
  140.                                 break;
  141.                         case 'mod_adminenhance_banimg':
  142.                                 $fp = fopen($this->imgfile, 'a');
  143.                                 foreach($PIO->fetchPosts($param) as $th){
  144.                                         if($th['md5chksum']) fwrite($fp, $th['md5chksum']."\n");
  145.                                 }
  146.                                 fclose($fp);
  147.                                 $message .= '圖檔黑名單更新完成<br />';
  148.                                 break;
  149.                         default:
  150.                 }
  151.         }
  152.        
  153.         function autoHookPostInfo(&$postinfo){
  154.                 $postinfo .= "<li>本版因各種原因有鎖關鍵字,請至<a href='".$this->mypage."&amp;action=listwords' rel='_blank'>字詞黑名單一覽</a>查詢。</li>\n";
  155.         }
  156.  
  157.         function autoHookLinksAboveBar(&$link, $pageId, $addinfo=false){
  158.                 if($pageId == 'admin' && $addinfo == true)
  159.                         $link .= '[<a href="'.$this->mypage.'">封鎖黑名單管理</a>]';
  160.         }
  161.        
  162.                 function autoHookThreadPost(&$arrLabels, $post, $isReply){
  163.                 global $PIO;
  164.                 $fh = new FlagHelper($post['status']);
  165.                 if($fh->value('asage')) { // 強制sage
  166.                         if($arrLabels['{$COM}']) $arrLabels['{$WARN_ENDREPLY}'].='<span class="warn_txt">此討論串已被強制sage,可繼續留言但不會浮上去。<br/></span>';
  167.                         else $arrLabels['{$WARN_ENDREPLY}'] = '<span class="warn_txt">此討論串已被強制sage,可繼續留言但不會浮上去。<br/></span>';
  168.                 }
  169.         }
  170.        
  171.         function autoHookThreadReply(&$arrLabels, $post, $isReply){
  172.                 $this->autoHookThreadPost($arrLabels, $post, $isReply);
  173.         }
  174.        
  175.         function autoHookRegistBeforeCommit(&$name, &$email, &$sub, &$com, &$category, &$age, $dest, $isReply, $imgWH, &$status){
  176.                 global $PIO;
  177.                 $fh = new FlagHelper($status);
  178.  
  179.                 if($isReply) {
  180.                         $rpost = $PIO->fetchPosts($isReply); // 強制sage
  181.                         $rfh = new FlagHelper($rpost[0]['status']);
  182.                         if($rfh->value('asage')) $age = false;
  183.                 }
  184.  
  185.         }
  186.  
  187.         function ModulePage(){
  188.                 global $PMS;
  189.                
  190.                 if(isset($_GET['action'])) {
  191.                         if($_GET['action'] == 'listwords') {
  192.                                 $dat = '';
  193.                                 $dat .= '字詞黑名單一覽<br /><hr />';
  194.                                 $dat .= '<table border="0" width="100%"><tr><td>Word</td><td>Description</td></tr>';
  195.                                
  196.                                 foreach($this->_parseBlackListFile($this->wordfile) as $i => $l){
  197.                                         $dat .= '<tr><td>'.htmlspecialchars($l[0]).'</td><td>'.(isset($l[1]) ? $l[1] : '').'</td></tr>'."\n";
  198.                                 }
  199.                                
  200.                                 $dat .= '</table>';
  201.                                 echo $dat;
  202.                                 return;
  203.                         }
  204.                 }
  205.                
  206.                 if(!adminAuthenticate('check')) die('[Error] Access Denied.');
  207.  
  208.                 // 進行新增、刪除等動作
  209.                 if(isset($_POST['operate'])){
  210.                         $op = $_POST['operate'];
  211.                         // 新增資料
  212.                         $ndata = isset($_POST['newdata']) ? (get_magic_quotes_gpc() ? stripslashes($_POST['newdata']) : $_POST['newdata']) : ''; // 資料內容
  213.                         $nperiod = isset($_POST['newperiod']) ? intval($_POST['newperiod']) : 0; // 封鎖天數
  214.                         $ndesc = isset($_POST['newdesc']) ? CleanStr($_POST['newdesc']) : ''; // 註解
  215.                         // 刪除資料
  216.                         $del = isset($_POST['del']) ? $_POST['del'] : null;
  217.                         $newline = '';
  218.                         $ismodified = ($ndata != '' || $del != null); // 是否需要修改檔案內容
  219.                         if($ismodified){
  220.                                 switch($op){
  221.                                         case 'ip':
  222.                                                 $file = $this->ipfile;
  223.                                                 if($ndata != '') $newline = $ndata."\t".$ndesc."\t".time()."\t".$nperiod."\n";
  224.                                                 break;
  225.                                         case 'img':
  226.                                                 $file = $this->imgfile;
  227.                                                 if($ndata != '') $newline = $ndata."\t".$ndesc."\n";
  228.                                                 break;
  229.                                         case 'word':
  230.                                                 $file = $this->wordfile;
  231.                                                 if($ndata != '') $newline = $ndata."\t".$ndesc."\n";
  232.                                                 break;
  233.                                 }
  234.                                 $this->_arrangeRecord($file, $del, $newline); // 同步進行刪除及更新
  235.                         }
  236.                         if(isset($_POST['ajax'])){ // AJAX 要求在此即停止,一般要求則繼續印出頁面
  237.                                 $extend = ($op=='ip') ? '<td>'.date('Y/m/d H:m:s', time())." ($nperiod)</td>" : ''; // IP黑名單資訊比圖檔多
  238.                                 echo '<tr><td>'.htmlspecialchars($ndata).'</td><td>'.$ndesc.'</td>'.$extend.'<td><input type="checkbox" name="del[]" value="#NO#" /></td></tr>';
  239.                                 return;
  240.                         }
  241.                 }
  242.  
  243.                 $dat = '';
  244.                 $PMS->hookModuleMethod('Head', array(&$this, '_hookHeadCSS'));
  245.                 head($dat);
  246.                 $dat .= '<div class="bar_admin">封鎖黑名單管理</div>
  247. <div id="content">
  248. <form action="'.$this->mypage.'" method="post">
  249. <div id="ipconfig"><input type="hidden" name="operate" value="ip" />
  250. IP 黑名單<br />
  251. Pattern: <input type="text" name="newdata" size="30" />
  252. Period: <input type="text" name="newperiod" size="5" value="0" />Day(s)
  253. Desc: <input type="text" name="newdesc" size="30" />
  254. <input type="submit" value="新增" onclick="return add(this.form);" /><br />
  255. <div class="dos_list_short">
  256. <table border="0" width="100%">
  257. <tr><td>Pattern</td><td>Description</td><td>Add Date (Period)</td><td>Delete</td></tr>
  258. ';
  259.                 foreach($this->_parseBlackListFile($this->ipfile) as $i => $l){
  260.                         $dat .= '<tr><td>'.htmlspecialchars($l[0]).'</td><td>'.(isset($l[1]) ? $l[1] : '').'</td>'.
  261.                         '<td>'.(isset($l[2]) ? date('Y/m/d H:m:s', $l[2]) : '-').(isset($l[3]) ? ' ('.$l[3].')' : ' (0)').'</td>'.
  262.                         '<td><input type="checkbox" name="del[]" value="'.$i.'" /></td></tr>'."\n";
  263.                 }
  264.                 $dat .= '</table>
  265. </div>
  266. <input type="submit" value="刪除" />
  267. </div>
  268. </form>
  269.  
  270. <form action="'.$this->mypage.'" method="post">
  271. <div id="imgconfig"><input type="hidden" name="operate" value="img" />
  272. 圖檔 MD5 黑名單<br />
  273. MD5: <input type="text" name="newdata" size="30" />
  274. Desc: <input type="text" name="newdesc" size="30" />
  275. <input type="hidden" name="newperiod" value="0" />
  276. <input type="submit" value="新增" onclick="return add(this.form);" /><br />
  277. <div class="dos_list_short">
  278. <table border="0" width="100%">
  279. <tr><td>MD5</td><td>Description</td><td>Delete</td></tr>
  280. ';
  281.                 foreach($this->_parseBlackListFile($this->imgfile) as $i => $l){
  282.                         $dat .= '<tr><td>'.htmlspecialchars($l[0]).'</td><td>'.(isset($l[1]) ? $l[1] : '').'</td><td><input type="checkbox" name="del[]" value="'.$i.'" /></td></tr>'."\n";
  283.                 }
  284.                 $dat .= '</table>
  285. </div>
  286. <input type="submit" value="刪除" />
  287. </div>
  288. </form>
  289.  
  290. <form action="'.$this->mypage.'" method="post">
  291. <div id="wordconfig"><input type="hidden" name="operate" value="word" />
  292. 字詞黑名單<br />
  293. Word: <input type="text" name="newdata" size="100" />
  294. Desc: <input type="text" name="newdesc" size="30" />
  295. <input type="submit" value="新增" onclick="return add(this.form);" /><br />
  296. <div class="dos_list_short">
  297. <table border="0" width="100%">
  298. <tr><td>Word</td><td>Description</td><td>Delete</td></tr>
  299. ';
  300.                 foreach($this->_parseBlackListFile($this->wordfile) as $i => $l){
  301.                         $dat .= '<tr><td>'.htmlspecialchars($l[0]).'</td><td>'.(isset($l[1]) ? $l[1] : '').'</td><td><input type="checkbox" name="del[]" value="'.$i.'" /></td></tr>'."\n";
  302.                 }
  303.                 $dat .= '</table>
  304. </div>
  305. <input type="submit" value="刪除" />
  306. </div>
  307. </form>
  308.  
  309. <hr />
  310. <div id="help"><pre>
  311. 說明
  312.  
  313. Pattern:
  314.  
  315. 可封鎖特定IP/Hostname發文。以使用者的IP位置或Host名稱進行判斷,所以兩種形式都可以使用。
  316. 例如 127.0.0.1 (IP) 和 localhost (Host) 代表的都是相同的電腦。
  317. 接受下列格式
  318.  
  319. - 完全相符
  320. 即是完全一模一樣的情況下才封鎖。
  321. 範例:
  322. 127.0.0.1 (127.0.0.1 O;127.0.0.2 X)
  323. localhost (localhost O;local X)
  324.  
  325. - 萬用字元
  326. 可接受 * , ? 來代替一段未知的字元 (如同大家熟知的使用方式),這樣一來可匹配的情況將增加。
  327. 範例:
  328. 192.168.0.* (192.168.0.3 O;192.168.1.3 X)
  329. local* (localhost O;remotehost X)
  330.  
  331. - 正規表達式
  332. 使用Regular Expression來進行匹配,可作出更多樣、更適合的條件。注意使用時需要使用 / 斜線將表達式括住。
  333. 範例:
  334. /127\.0\.0\.[0-9]{2}/ (127.0.0.28 O;127.0.0.1 X)
  335. /^.+\.proxy\.com$/ (gate1.proxy.com O;proxy2.com.tw X)
  336.  
  337. - CIDR Notation
  338. 使用 Classless Addressing 這種更有彈性的方式切割子網路,其表示法稱作 CIDR,以一段IP位置加上Mask來劃分子網路 (注意此表示法僅能使用 IP)。
  339. 範例:
  340. 192.168.0.1/20 (192.168.7.243 O;192.168.18.144 X)
  341.  
  342. Period:
  343.  
  344. 設定封鎖期限,在過期時可以自動刪除解鎖,以天為單位。如果想永久封鎖 (系統不自動回收,需手動解鎖) 則將此值設為 0 (0 表示無期限)。
  345.  
  346. Banword:
  347.  
  348. 可封鎖特定字詞發文,只支援以下一種格式:
  349.  
  350. - 完全相符
  351. 即是完全一模一樣的情況下才封鎖。
  352. 範例:
  353. 果然棒 (果然棒123 O;果然...棒 X)
  354. 活佛 (信活佛 O;活-佛 X)
  355. </pre>
  356. </div>
  357. </div>';
  358.                 foot($dat);
  359.                 echo $dat;
  360.         }
  361. }
  362.  
  363. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement