[SCRIPT] Бан за дюп по логам

Тема в разделе "Веб скрипты (WEB)", создана пользователем root, 1 окт 2014.

  1. root

    root Administrator Команда форума Administrator Moderator Developers Team

    Регистрация:
    23 авг 2014
    Сообщения:
    253
    Симпатии:
    56
    Баллы:
    11
    Код:
    <?php // Бан за дюп (c) gogi79 
    // Актуально, если используется logD, без logD хз будет ли работать. 
    
    
    $cur_dir = dirname(__FILE__); 
    $dir_err_logs = "E:\\x50_server\\logD\\log\\err"; // Путь к директории в Error логами 
    $dir_in_logs = "E:\\x50_server\\logD\\log\\in"; // Путь к директории с IN логами 
    
    
    // тип наказания 
    $array_dup1 = array(); // 1 список - это те, кто скорее всего дюпал 100% 
    $array_dup2 = array(); // 2 список - это те, кто попал до кучи, вероятно среди них дюпер, надо ручками проверять. (редко бывает) 
    // три типа наказания: 
    // 1 = бан всех твинков + kick чаров из игры 
    // 2 = бан только текущего акка + kick чара из игры 
    // 3 = только лог, без банов 
    $type1 = 1; // Наказание для 1 списка 
    $type2 = 2; // Наказание для 2 списка 
    
    
    // Функции Кэшеда 
    
    
    function tounicode($string) { 
        $rs=""; 
        for($i=0;$i<strlen($string);$i++) { 
            $rs.=$string[$i].chr(0); 
        } 
        return($rs.chr(0).chr(0)); 
    } 
    
    
    function CheckChar($char_id) { 
        $buf=pack("cV",1,$char_id); 
        [email protected]("127.0.0.1","2012",&$errno,&$errstr,5); 
        if ($cachedsocket) { 
            fwrite($cachedsocket,pack("s",(strlen($buf)+2)).$buf); 
            $len=unpack("v",fread($cachedsocket,2)); 
            $rid=unpack("c",fread($cachedsocket,1)); 
            $rs=""; 
            for ($i=0; $i<(($len[1]-4)/4); $i++) { 
                $read=unpack("i",fread($cachedsocket,4)); 
                $rs.=$read[1]; 
            } 
            fclose($cachedsocket); 
            return $rs; 
        } else { 
            return false; 
        } 
    } 
    
    
    function kick_char($id) { 
        [email protected]("127.0.0.1","2012",&$errno,&$errstr,5); 
        if ($cachedsocket) { 
            $buf=pack("c",5); 
            $buf.=pack("i",$id); 
            $buf.=tounicode("admin"); 
            fwrite($cachedsocket,pack("s",(strlen($buf)+2)).$buf); 
            $len=unpack("v",fread($cachedsocket,2)); 
            $rid=unpack("c",fread($cachedsocket,1)); 
            $rs=""; 
            for ($i=0; $i<(($len[1]-4)/4); $i++) { 
                $read=unpack("i",fread($cachedsocket,4)); 
                $rs.=$read[1]; 
            } 
            fclose($cachedsocket); 
            return $rs; 
        } else { 
            return false; 
        } 
    } 
    
    
    function err_log($str) { 
        global $cur_dir; 
        $fp = fopen($cur_dir."\\log\\".date("Y_m_d-H")."_Err.log","a"); 
        fputs($fp, date("H:i:s")." ".$str."\r\n"); 
        fclose($fp); 
    } 
    
    
    function dir_list($dir) { 
        $list = array(); // Массив сортировка по дате модификации файлов 
        if ($handle = opendir($dir)) { 
            while (false !== ($file = readdir($handle))) { 
                if ($file != "." && $file != "..") { 
                    $list[$file] = filemtime($dir."\\".$file); 
                } 
            } 
            closedir($handle); 
        } else { 
            return false; 
        } 
        if (count($list)>0) { 
            arsort($list); 
            return $list; 
        } 
        return false; 
    } 
    
    
    // Поиск dbid[0] в Err cached логе 
    $err_files = dir_list($dir_err_logs); 
    if ($err_files === false) { 
        die(); 
    } 
    $lastfile = null; 
    foreach ($err_files as $filename => $lastmod) { 
        if (strpos($filename,"-cached-") !== false) { 
            $lastfile = $filename; 
            break; 
        } 
    } 
    if (!$lastfile) { 
        die(); 
    } 
    $fp = fopen($dir_err_logs."\\".$lastfile,"r"); 
    $errfarr = array(); 
    while (!feof($fp)) { 
        $line = fgets($fp); 
        // 12/29/2008 15:56:06.078, [.\WareHouse.cpp][3611] Try hack ? . dbid[0] 
        if (strpos($line," dbid[0]") === false) continue; 
        if (preg_match("~^(([0-9]{2})/([0-9]{2})/([0-9]{4}) ([0-9]{2}):([0-9]{2}):([0-9]{2})\.[0-9]{1,4}), ~",$line,$match)) { 
            $fulltimestr = $match[1]; 
            $timestamp = mktime(intval($match[5]), intval($match[6]), intval($match[7]), intval($match[2]), intval($match[3]), $match[4]); 
            $errfarr[$fulltimestr] = $timestamp; 
        } 
    } 
    fclose($fp); 
    // Проверяем массив, есть ли нахождения dbid[0] в текущем логе. 
    $counterr = count($errfarr); 
    if ($counterr<1) die(); // ничего нет, завершаем работу. 
    
    
    // Проверяем кэш файл на наличие совпадений, если он есть 
    $cachearr = array(); 
    if (file_exists($cur_dir."\\tmp\\".date("Ymd").".txt")) { 
        $f = file($cur_dir."\\tmp\\".date("Ymd").".txt"); 
        for ($i=0;$i<count($f);$i++) { 
            $cachearr[rtrim($f[$i])] = 1; 
        } 
    } 
    $newerr = array(); 
    foreach ($errfarr as $tstr => $tstamp) { 
        if (isset($cachearr[$tstr])) continue; 
        $newerr[$tstr] = $tstamp; 
    } 
    if (count($newerr)<1) die(); // нет новых ошибок, завершаем работу. 
    
    
    // Лог server IN 
    $in_files = dir_list($dir_in_logs); 
    if ($in_files === false) { 
        die(); 
    } 
    $errmodmax = max($newerr); 
    $logfile = null; 
    foreach ($in_files as $filename => $lastmod) { 
        if (strpos($filename,"-server-") !== false) { 
            if ($errmodmax <= $lastmod) { 
                $logfile = $filename; 
            } 
        } 
    } 
    if (!$logfile) { 
        err_log("Не смог найти файл server IN лога (".$errmodmax.")"); 
        die(); 
    } 
    
    
    // Читаем server IN лог, поиск Action 916 =+- 1 sec 
    $fp = fopen($dir_in_logs."\\".$logfile,"r"); 
    if ($fp) { 
        $fp2 = fopen($cur_dir."\\tmp\\".date("Ymd").".txt","w"); 
        foreach ($newerr as $tstr => $tstamp) { // 12/29/2008 15:30:00.281 
            $curtimestr = date("m/d/Y H:i:s.", $tstamp); 
            $mintimestr = date("m/d/Y H:i:s.", ($tstamp-1)); // минимальное время, строки которого запомним, -1 сек от события. 
            $maxtimestr = date("m/d/Y H:i:s.", ($tstamp+1)); // максимальное время от события, которое будем проверять тоже. +1 сек. округленная 
            $orig_time = $tstr; // приоритетное время, равно событию, если найдем совпадения в этом времени, тогда используем его. 
            $tmpstr = array(); // временные строки 
            $priorfound = false; 
            $j=0; 
            if (rewind($fp)===false) { 
                err_log("Курсор не установлен в начало файла (".$dir_in_logs."\\".$logfile.")"); // на всякий... 
                continue; 
            } 
            fputs($fp2,$tstr."\n"); // запись в кэш 
            while (!feof($fp)) { 
                $line = fgets($fp); 
                if (strpos($line,$mintimestr) !== false || strpos($line,$curtimestr) !== false) { 
                    if (strpos($line,", 916,") !== false) { 
                        $tmpstr[$j] = $line; 
                        if (strpos($line,$orig_time) !== false) { 
                            // приоритетное время 
                            $priorfound = $j; 
                        } 
                        $j++; 
                    } 
                } 
                if (strpos($line,$maxtimestr) !== false) break; 
            } 
            // Ищем 916 
            $counttmpstr = count($tmpstr); 
            if ($counttmpstr<1) { 
                // никуя не найдено, так тоже бывает... знач не судьба или ошибка (это не тот дюп) 
                err_log("Возможно дюп другого типа (".$dir_in_logs."\\".$logfile.") время в cached-err - ".$tstr.""); 
                continue; 
            } 
            // Если найдено приоритетное время, смотрим лог в этом времени и до этого времени. 
            $dupfound = array(); // массив с записями 916 которые находились в приоритетном времени 
            $oldfound = array(); // массив с записями 916 в другое время (если нет записей в $dupfound, банить будем этих) 
            if ($priorfound!==false) { 
                for ($i=$priorfound;$i>=0;$i--) { 
                    $exp = explode(",",$tmpstr[$i]); 
                    if ($exp[0] == $orig_time) { 
                        $dupfound[] = array($exp[0],$exp[22],$exp[23],$exp[24],$exp[25]); 
                    } else { 
                        $oldfound[] = array($exp[0],$exp[22],$exp[23],$exp[24],$exp[25]); 
                    } 
                } 
            } else { // если не найдено приоритетное время, пишем всех 
                foreach ($tmpstr as $val) { 
                    $exp = explode(",",$val); 
                    $oldfound[] = array($exp[0],$exp[22],$exp[23],$exp[24],$exp[25]); 
                } 
            } 
            // Расстановка записей по типам 
            if (count($dupfound)>0) { 
                $array_dup1[$tstr] = $dupfound; 
            } 
            if (count($oldfound)>0) { 
                $array_dup2[$tstr] = $oldfound; 
            } 
        } 
        fclose($fp); 
        fclose($fp2); 
    } else { 
        err_log("Не смог открыть файл (".$dir_in_logs."\\".$logfile.")"); 
    } 
    
    
    $MSSQL_CONNECT = mssql_connect("localhost","sa","Xk7gH9j"); 
    if (!$MSSQL_CONNECT) { 
        @mssql_close($MSSQL_CONNECT); 
    } 
    
    
    // Часть вторая, наказание и отчеты :P 
    $log_str = ""; 
    foreach ($newerr as $duptime => $val) { 
        $log_str .= "Ахтунг! Обнаружен дюп, время - $duptime\r\n------------------------------------------------------------------\r\n"; 
        if (is_array($array_dup1[$duptime])) { 
            $log_str .= "Найдены основные подозреваемые:\r\n"; 
            foreach ($array_dup1[$duptime] as $userlist) { 
                $log_str .= $userlist[0]." / ".$userlist[1].":".$userlist[2]." - ".$userlist[3].":".$userlist[4]."\r\n"; 
                // Ищем в базе 
                if ($MSSQL_CONNECT) { 
                    if ($type1 == 1 || $type1 == 2) { 
                        $banacc = array(); 
                        $sql = mssql_query("SELECT char_id, char_name, account_name FROM [lin2world].[dbo].[user_data] WHERE char_name IN ('".$userlist[1]."','".$userlist[3]."')",$MSSQL_CONNECT); 
                        if (mssql_num_rows($sql)>0) { 
                            while (list($char_id,$char_name,$account_name) = mssql_fetch_row($sql)) { 
                                $CheckChar = CheckChar($char_id); 
                                if ($CheckChar === false) { 
                                    kick_char($char_id); 
                                    sleep(1); 
                                } 
                                kick_char($char_id); 
                                $banacc[] = $account_name; 
                            } 
                        } 
                        if ($type1 == 1) { 
                            if (count($banacc)==2) { 
                                mssql_query("UPDATE [lin2db].[dbo].[user_account] SET pay_stat = 0 WHERE (hkey IN (SELECT hkey FROM [lin2db].[dbo].[user_account] WHERE (account IN ('".implode("','",$banacc)."'))))",$MSSQL_CONNECT); 
                            } else { 
                                mssql_query("UPDATE [lin2db].[dbo].[user_account] SET pay_stat = 0 WHERE (hkey IN (SELECT hkey FROM [lin2db].[dbo].[user_account] WHERE (account IN ('".$userlist[2]."','".$userlist[4]."'))))",$MSSQL_CONNECT); 
                            } 
                            $log_str .= "Забанены аккаунты: ".implode(", ",$banacc)." со всеми твинками\r\n"; 
                        } elseif ($type1 == 2) { 
                            if (count($banacc)==2) { 
                                mssql_query("UPDATE [lin2db].[dbo].[user_account] SET pay_stat = 0 WHERE (account IN ('".implode("','",$banacc)."'))",$MSSQL_CONNECT); 
                            } else { 
                                mssql_query("UPDATE [lin2db].[dbo].[user_account] SET pay_stat = 0 WHERE (account IN ('".$userlist[2]."','".$userlist[4]."'))",$MSSQL_CONNECT); 
                            } 
                            $log_str .= "Забанены аккаунты: ".implode(", ",$banacc)."\r\n"; 
                        } 
                    } 
                } 
            } 
        } 
        if (is_array($array_dup2[$duptime])) { 
            $log_str .= "Найдены другие подозреваемые:\r\n"; 
            foreach ($array_dup2[$duptime] as $userlist) { 
                $log_str .= $userlist[0]." / ".$userlist[1].":".$userlist[2]." - ".$userlist[3].":".$userlist[4]."\r\n"; 
                // Ищем в базе 
                if ($MSSQL_CONNECT) { 
                    if ($type2 == 1 || $type2 == 2) { 
                        $banacc = array(); 
                        $sql = mssql_query("SELECT char_id, char_name, account_name FROM [lin2world].[dbo].[user_data] WHERE char_name IN ('".$userlist[1]."','".$userlist[3]."')",$MSSQL_CONNECT); 
                        if (mssql_num_rows($sql)>0) { 
                            while (list($char_id,$char_name,$account_name) = mssql_fetch_row($sql)) { 
                                $CheckChar = CheckChar($char_id); 
                                if ($CheckChar === false) { 
                                    kick_char($char_id); 
                                    sleep(1); 
                                } 
                                kick_char($char_id); 
                                $banacc[] = $account_name; 
                            } 
                        } 
                        if ($type2 == 1) { 
                            if (count($banacc)==2) { 
                                mssql_query("UPDATE [lin2db].[dbo].[user_account] SET pay_stat = 0 WHERE (hkey IN (SELECT hkey FROM [lin2db].[dbo].[user_account] WHERE (account IN ('".implode("','",$banacc)."'))))",$MSSQL_CONNECT); 
                            } else { 
                                mssql_query("UPDATE [lin2db].[dbo].[user_account] SET pay_stat = 0 WHERE (hkey IN (SELECT hkey FROM [lin2db].[dbo].[user_account] WHERE (account IN ('".$userlist[2]."','".$userlist[4]."'))))",$MSSQL_CONNECT); 
                            } 
                            $log_str .= "Забанены аккаунты: ".implode(", ",$banacc)." со всеми твинками\r\n"; 
                        } elseif ($type2 == 2) { 
                            if (count($banacc)==2) { 
                                mssql_query("UPDATE [lin2db].[dbo].[user_account] SET pay_stat = 0 WHERE (account IN ('".implode("','",$banacc)."'))",$MSSQL_CONNECT); 
                            } else { 
                                mssql_query("UPDATE [lin2db].[dbo].[user_account] SET pay_stat = 0 WHERE (account IN ('".$userlist[2]."','".$userlist[4]."'))",$MSSQL_CONNECT); 
                            } 
                            $log_str .= "Забанены аккаунты: ".implode(", ",$banacc)."\r\n"; 
                        } 
                    } 
                } 
            } 
        } 
        $log_str .= "------------------------------------------------------------------\r\n\r\n"; 
    } 
    
    
    @mssql_close($MSSQL_CONNECT); 
    
    
    $fp = fopen($cur_dir."\\log\\".date("Y_m_d_H_i_s").".log","w"); 
    fputs($fp,$log_str); 
    fclose($fp); 
    ?>
     
  2. root

    root Administrator Команда форума Administrator Moderator Developers Team

    Регистрация:
    23 авг 2014
    Сообщения:
    253
    Симпатии:
    56
    Баллы:
    11
    Более новая версия:
    Код:
    <?php // Бан за дюп (c) gogi79  / 16-02-2010 
    // Актуально, если используется logD, без logD хз будет ли работать. 
    // Нужно создать  в одной директории со скриптом 2 папки: log и tmp туда будут отчеты сваливаться, если будет найден дюп. 
    // Скрипт запускаем каждые 2-3 минуты, по расписанию. 
    //  Структура запросов в базу сделана в расчете на то, что вы используете защиту авторизации от Hint'а, или переписывайте запросы. 
    // так как поиск твинков для бана ищется по hkey. 
    
    
    $cur_dir = dirname(__FILE__); 
    //$dir_err_logs = "G:\\logd\\log\\err"; // Путь к директории в Error логами 
    //$dir_in_logs = "G:\\logd\\log\\in"; // Путь к директории с IN логами 
    $dir_err_logs = "I:\\logd\\log\\err"; // X:\\dup 
    $dir_in_logs = "I:\\logd\\log\\in"; 
    
    
    // тип наказания 
    $array_dup1 = array(); // 1 список - это те, кто скорее всего дюпал 100% 
    $array_dup2 = array(); // 2 список - это те, кто попал до кучи, вероятно среди них дюпер, надо ручками проверять. (редко бывает) 
    // три типа наказания: 
    // 1 = бан всех твинков + kick чаров из игры 
    // 2 = бан только текущего акка + kick чара из игры 
    // 3 = только лог, без банов 
    $type1 = 1; // Наказание для 1 списка 
    $type2 = 2; // Наказание для 2 списка 
    
    
    // Функции Кэшеда 
    
    
    function tounicode($string) { 
        $rs=""; 
        for($i=0;$i<strlen($string);$i++) { 
            $rs.=$string[$i].chr(0); 
        } 
        return($rs.chr(0).chr(0)); 
    } 
    
    
    function CheckChar($char_id) { 
        $buf=pack("cV",1,$char_id); 
        [email protected]("127.0.0.1","2012",&$errno,&$errstr,5); 
        if ($cachedsocket) { 
            fwrite($cachedsocket,pack("s",(strlen($buf)+2)).$buf); 
            $len=unpack("v",fread($cachedsocket,2)); 
            $rid=unpack("c",fread($cachedsocket,1)); 
            $rs=""; 
            for ($i=0; $i<(($len[1]-4)/4); $i++) { 
                $read=unpack("i",fread($cachedsocket,4)); 
                $rs.=$read[1]; 
            } 
            fclose($cachedsocket); 
            return $rs; 
        } else { 
            return false; 
        } 
    } 
    
    
    function kick_char($id) { 
        [email protected]("127.0.0.1","2012",&$errno,&$errstr,5); 
        if ($cachedsocket) { 
            $buf=pack("c",5); 
            $buf.=pack("i",$id); 
            $buf.=tounicode("admin"); 
            fwrite($cachedsocket,pack("s",(strlen($buf)+2)).$buf); 
            $len=unpack("v",fread($cachedsocket,2)); 
            $rid=unpack("c",fread($cachedsocket,1)); 
            $rs=""; 
            for ($i=0; $i<(($len[1]-4)/4); $i++) { 
                $read=unpack("i",fread($cachedsocket,4)); 
                $rs.=$read[1]; 
            } 
            fclose($cachedsocket); 
            return $rs; 
        } else { 
            return false; 
        } 
    } 
    
    
    function err_log($str) { 
        global $cur_dir; 
        $fp = fopen($cur_dir."\\log\\".date("Y_m_d-H")."_Err.log","a"); 
        fputs($fp, date("H:i:s")." ".$str."\r\n"); 
        fclose($fp); 
    } 
    
    
    function dir_list($dir) { 
        $list = array(); // Массив сортировка по дате модификации файлов 
        if ($handle = opendir($dir)) { 
            while (false !== ($file = readdir($handle))) { 
                if ($file != "." && $file != "..") { 
                    $list[$file] = filemtime($dir."\\".$file); 
                } 
            } 
            closedir($handle); 
        } else { 
            return false; 
        } 
        if (count($list)>0) { 
            arsort($list); 
            return $list; 
        } 
        return false; 
    } 
    
    
    // Поиск dbid[0] в Err cached логе 
    $err_files = dir_list($dir_err_logs); 
    if ($err_files === false) { 
        die(); 
    } 
    $lastfile = null; 
    foreach ($err_files as $filename => $lastmod) { 
        if (strpos($filename,"-cached-") !== false) { 
            $lastfile = $filename; 
            break; 
        } 
    } 
    if (!$lastfile) { 
        die(); 
    } 
    $fp = fopen($dir_err_logs."\\".$lastfile,"r"); 
    $errfarr = array(); 
    $errfarr2 = array(); 
    while (!feof($fp)) { 
        $line = fgets($fp); 
        // Дюп через трейд 
        // 12/29/2008 15:56:06.078, [.\WareHouse.cpp][3611] Try hack ? . dbid[0] 
        if (strpos($line," dbid[0]") !== false) { 
            if (preg_match("~^(([0-9]{2})/([0-9]{2})/([0-9]{4}) ([0-9]{2}):([0-9]{2}):([0-9]{2})\.[0-9]{1,4}), ~",$line,$match)) { 
                $fulltimestr = $match[1]; 
                $timestamp = mktime(intval($match[5]), intval($match[6]), intval($match[7]), intval($match[2]), intval($match[3]), $match[4]); 
                $errfarr[$fulltimestr] = $timestamp; 
            } 
            continue; 
        } 
        // Дюп через варехауз 
        // 09/23/2009 01:50:04.156, [.\WareHouse.cpp][3555] Try hack ? . dbid[4500676] 
        if (strpos($line,"Try hack ? . dbid[") !== false) { 
            if (preg_match("~dbid\[([0-9]+)\]~",$line,$m_dbid)) { 
                $dbid = $m_dbid[1]; 
                if (preg_match("~^(([0-9]{2})/([0-9]{2})/([0-9]{4}) ([0-9]{2}):([0-9]{2}):([0-9]{2})\.[0-9]{1,4}), ~",$line,$match)) { 
                    $fulltimestr = $match[1]; 
                    $timestamp = mktime(intval($match[5]), intval($match[6]), intval($match[7]), intval($match[2]), intval($match[3]), $match[4]); 
                    if ($dbid>0) { 
                        $errfarr2[$fulltimestr] = array($timestamp,$dbid); 
                    } 
                } 
            } 
            continue; 
        } 
    } 
    fclose($fp); 
    // Проверяем массив, есть ли нахождения dbid[0] в текущем логе. 
    $counterr = count($errfarr); 
    $counterr2 = count($errfarr2); 
    if ($counterr<1 && $counterr2<1) die(); // ничего нет, завершаем работу. 
    
    
    // Connect Game server 
    $MSSQL_CONNECT = mssql_connect("localhost","sa","pass"); 
    if (!$MSSQL_CONNECT) { 
        @mssql_close($MSSQL_CONNECT); 
    } 
    
    
    // Connect Login server 
    $MSSQL_CONNECT1 = mssql_connect("sql.bestworld.ru","sa","pass",true); 
    if (!$MSSQL_CONNECT1) { 
        @mssql_close($MSSQL_CONNECT1); 
    } 
    
    
    // Если есть ошибки во 2м массиве 
    if ($counterr2>0) { 
        // Проверяем кэш файл на наличие совпадений, если он есть 
        $cachearr2 = array(); 
        if (file_exists($cur_dir."\\tmp\\2err_".date("Ymd").".txt")) { 
            $f = file($cur_dir."\\tmp\\2err_".date("Ymd").".txt"); 
            for ($i=0;$i<count($f);$i++) { 
                $cachearr2[rtrim($f[$i])] = 1; 
            } 
        } 
        $newerr2 = array(); 
        foreach ($errfarr2 as $tstr => $tstamp) { 
            if (isset($cachearr2[$tstr])) continue; 
            $newerr2[$tstr] = $tstamp; 
        } 
        if (count($newerr2)>0) { // Если есть новые ошибки 
            $fp = fopen($cur_dir."\\tmp\\2err_".date("Ymd").".txt","w"); 
            foreach ($newerr2 as $ftimes => $dataarr) { 
                if ($MSSQL_CONNECT) { 
                    $sql = mssql_query("SELECT TOP 1 A.item_type, A.amount, A.warehouse, A.char_id, B.char_name, B.account_name, B.account_id FROM [lin2world].[dbo].[user_item] AS A LEFT OUTER JOIN [lin2world].[dbo].[user_data] AS B ON B.char_id = A.char_id WHERE (A.item_id = ".$dataarr[1].")",$MSSQL_CONNECT); 
                    $mes_log = "Ахтунг! Обнаружен дюп через warehouse, время - $ftimes\r\n------------------------------------------------------------------\r\n"; 
                    if (mssql_num_rows($sql)>0) { 
                        list($db_item_type,$db_amount,$db_warehouse,$db_char_id,$db_char_name,$db_account_name,$db_account_id) = mssql_fetch_row($sql); 
                        if ($db_char_id>0) { 
                            $CheckChar = CheckChar($db_char_id); 
                            if ($CheckChar === false) { 
                                kick_char($db_char_id); 
                                sleep(1); 
                            } 
                            kick_char($db_char_id); 
                            // Бан 
                            mssql_query("UPDATE [lin2db].[dbo].[user_account] SET pay_stat = 0 WHERE (hkey IN (SELECT hkey FROM [lin2db].[dbo].[user_account] WHERE (account IN ('".$db_account_name."'))))",$MSSQL_CONNECT1); 
                            $mes_log .= "DBid - ".$dataarr[1]."\r\n"; 
                            $mes_log .= "Итем - $db_item_type\r\n"; 
                            $mes_log .= "Кол-во - $db_amount\r\n"; 
                            $mes_log .= "Склад - $db_warehouse\r\n"; 
                            $mes_log .= "Имя чара - $db_char_name\r\n"; 
                            $mes_log .= "Аккаунт - $db_account_name\r\n"; 
                        } else { 
                            $mes_log .= "Запрос в базу вернул удаленный итем, проверить нужно DBID - ".$dataarr[1]."\r\n"; 
                        } 
                    } else { 
                        // Пишем в лог, что не найден итем. 
                        $mes_log .= "Запрос в базу не вернул результата, проверить нужно DBID - ".$dataarr[1]."\r\n"; 
                    } 
                    $mes_log .= "------------------------------------------------------------------\r\n\r\n"; 
                    fputs($fp,$ftimes."\n"); // запись в кэш 
                    $fp2 = fopen($cur_dir."\\log\\".date("Y_m_d_H_i_s").".log","w"); 
                    fputs($fp2,$mes_log); 
                    fclose($fp2); 
                } 
            } 
            fclose($fp); 
        } 
    } 
    
    
    if ($counterr<1) die(); // нет ошибок 1ого массива, завершаем работу. 
    
    
    // Проверяем кэш файл на наличие совпадений, если он есть 
    $cachearr = array(); 
    if (file_exists($cur_dir."\\tmp\\1err_".date("Ymd").".txt")) { 
        $f = file($cur_dir."\\tmp\\1err_".date("Ymd").".txt"); 
        for ($i=0;$i<count($f);$i++) { 
            $cachearr[rtrim($f[$i])] = 1; 
        } 
    } 
    
    
    $newerr = array(); 
    foreach ($errfarr as $tstr => $tstamp) { 
        if (isset($cachearr[$tstr])) continue; 
        $newerr[$tstr] = $tstamp; 
    } 
    if (count($newerr)<1) die(); // нет новых ошибок, завершаем работу. 
    
    
    // Лог server IN 
    $in_files = dir_list($dir_in_logs); 
    if ($in_files === false) { 
        die(); 
    } 
    $errmodmax = max($newerr); 
    $logfile = null; 
    foreach ($in_files as $filename => $lastmod) { 
        if (strpos($filename,"-server-") !== false) { 
            if ($errmodmax <= $lastmod) { 
                $logfile = $filename; 
            } 
        } 
    } 
    if (!$logfile) { 
        err_log("Не смог найти файл server IN лога (".$errmodmax.")"); 
        die(); 
    } 
    
    
    // Читаем server IN лог, поиск Action 916 =+- 1 sec 
    $fp = fopen($dir_in_logs."\\".$logfile,"r"); 
    if ($fp) { 
        $fp2 = fopen($cur_dir."\\tmp\\1err_".date("Ymd").".txt","w"); 
        foreach ($newerr as $tstr => $tstamp) { // 12/29/2008 15:30:00.281 
            $curtimestr = date("m/d/Y H:i:s.", $tstamp); 
            $mintimestr = date("m/d/Y H:i:s.", ($tstamp-1)); // минимальное время, строки которого запомним, -1 сек от события. 
            $maxtimestr = date("m/d/Y H:i:s.", ($tstamp+1)); // максимальное время от события, которое будем проверять тоже. +1 сек. округленная 
            $orig_time = $tstr; // приоритетное время, равно событию, если найдем совпадения в этом времени, тогда используем его. 
            $tmpstr = array(); // временные строки 
            $priorfound = false; 
            $j=0; 
            if (rewind($fp)===false) { 
                err_log("Курсор не установлен в начало файла (".$dir_in_logs."\\".$logfile.")"); // на всякий... 
                continue; 
            } 
            fputs($fp2,$tstr."\n"); // запись в кэш 
            while (!feof($fp)) { 
                $line = fgets($fp); 
                if (strpos($line,$mintimestr) !== false || strpos($line,$curtimestr) !== false) { 
                    if (strpos($line,", 916,") !== false) { 
                        $tmpstr[$j] = $line; 
                        if (strpos($line,$orig_time) !== false) { 
                            // приоритетное время 
                            $priorfound = $j; 
                        } 
                        $j++; 
                    } 
                } 
                if (strpos($line,$maxtimestr) !== false) break; 
            } 
            // Ищем 916 
            $counttmpstr = count($tmpstr); 
            if ($counttmpstr<1) { 
                // никуя не найдено, так тоже бывает... знач не судьба или ошибка (это не тот дюп) 
                err_log("Возможно дюп другого типа (".$dir_in_logs."\\".$logfile.") время в cached-err - ".$tstr.""); 
                continue; 
            } 
            // Если найдено приоритетное время, смотрим лог в этом времени и до этого времени. 
            $dupfound = array(); // массив с записями 916 которые находились в приоритетном времени 
            $oldfound = array(); // массив с записями 916 в другое время (если нет записей в $dupfound, банить будем этих) 
            if ($priorfound!==false) { 
                for ($i=$priorfound;$i>=0;$i--) { 
                    $exp = explode(",",$tmpstr[$i]); 
                    if ($exp[0] == $orig_time) { 
                        $dupfound[] = array($exp[0],$exp[22],$exp[23],$exp[24],$exp[25]); 
                    } else { 
                        $oldfound[] = array($exp[0],$exp[22],$exp[23],$exp[24],$exp[25]); 
                    } 
                } 
            } else { // если не найдено приоритетное время, пишем всех 
                foreach ($tmpstr as $val) { 
                    $exp = explode(",",$val); 
                    $oldfound[] = array($exp[0],$exp[22],$exp[23],$exp[24],$exp[25]); 
                } 
            } 
            // Расстановка записей по типам 
            if (count($dupfound)>0) { 
                $array_dup1[$tstr] = $dupfound; 
            } 
            if (count($oldfound)>0) { 
                $array_dup2[$tstr] = $oldfound; 
            } 
        } 
        fclose($fp); 
        fclose($fp2); 
    } else { 
        err_log("Не смог открыть файл (".$dir_in_logs."\\".$logfile.")"); 
    } 
    
    
    // Часть вторая, наказание и отчеты :P 
    $log_str = ""; 
    foreach ($newerr as $duptime => $val) { 
        $log_str .= "Ахтунг! Обнаружен дюп, время - $duptime\r\n------------------------------------------------------------------\r\n"; 
        if (is_array($array_dup1[$duptime])) { 
            $log_str .= "Найдены основные подозреваемые:\r\n"; 
            foreach ($array_dup1[$duptime] as $userlist) { 
                $log_str .= $userlist[0]." / ".$userlist[1].":".$userlist[2]." - ".$userlist[3].":".$userlist[4]."\r\n"; 
                // Ищем в базе 
                if ($MSSQL_CONNECT && $MSSQL_CONNECT1) { 
                    if ($type1 == 1 || $type1 == 2) { 
                        $banacc = array(); 
                        $sql = mssql_query("SELECT char_id, char_name, account_name FROM [lin2world].[dbo].[user_data] WHERE char_name IN ('".$userlist[1]."','".$userlist[3]."')",$MSSQL_CONNECT); 
                        if (mssql_num_rows($sql)>0) { 
                            while (list($char_id,$char_name,$account_name) = mssql_fetch_row($sql)) { 
                                $CheckChar = CheckChar($char_id); 
                                if ($CheckChar === false) { 
                                    kick_char($char_id); 
                                    sleep(1); 
                                } 
                                kick_char($char_id); 
                                $banacc[] = $account_name; 
                            } 
                        } 
                        if ($type1 == 1) { 
                            if (count($banacc)==2) { 
                                mssql_query("UPDATE [lin2db].[dbo].[user_account] SET pay_stat = 0 WHERE (hkey IN (SELECT hkey FROM [lin2db].[dbo].[user_account] WHERE (account IN ('".implode("','",$banacc)."'))))",$MSSQL_CONNECT1); 
                            } else { 
                                mssql_query("UPDATE [lin2db].[dbo].[user_account] SET pay_stat = 0 WHERE (hkey IN (SELECT hkey FROM [lin2db].[dbo].[user_account] WHERE (account IN ('".$userlist[2]."','".$userlist[4]."'))))",$MSSQL_CONNECT1); 
                            } 
                            $log_str .= "Забанены аккаунты: ".implode(", ",$banacc)." со всеми твинками\r\n"; 
                        } elseif ($type1 == 2) { 
                            if (count($banacc)==2) { 
                                mssql_query("UPDATE [lin2db].[dbo].[user_account] SET pay_stat = 0 WHERE (account IN ('".implode("','",$banacc)."'))",$MSSQL_CONNECT1); 
                            } else { 
                                mssql_query("UPDATE [lin2db].[dbo].[user_account] SET pay_stat = 0 WHERE (account IN ('".$userlist[2]."','".$userlist[4]."'))",$MSSQL_CONNECT1); 
                            } 
                            $log_str .= "Забанены аккаунты: ".implode(", ",$banacc)."\r\n"; 
                        } 
                    } 
                } 
            } 
        } 
        if (is_array($array_dup2[$duptime])) { 
            $log_str .= "Найдены другие подозреваемые:\r\n"; 
            foreach ($array_dup2[$duptime] as $userlist) { 
                $log_str .= $userlist[0]." / ".$userlist[1].":".$userlist[2]." - ".$userlist[3].":".$userlist[4]."\r\n"; 
                // Ищем в базе 
                if ($MSSQL_CONNECT && $MSSQL_CONNECT1) { 
                    if ($type2 == 1 || $type2 == 2) { 
                        $banacc = array(); 
                        $sql = mssql_query("SELECT char_id, char_name, account_name FROM [lin2world].[dbo].[user_data] WHERE char_name IN ('".$userlist[1]."','".$userlist[3]."')",$MSSQL_CONNECT); 
                        if (mssql_num_rows($sql)>0) { 
                            while (list($char_id,$char_name,$account_name) = mssql_fetch_row($sql)) { 
                                $CheckChar = CheckChar($char_id); 
                                if ($CheckChar === false) { 
                                    kick_char($char_id); 
                                    sleep(1); 
                                } 
                                kick_char($char_id); 
                                $banacc[] = $account_name; 
                            } 
                        } 
                        if ($type2 == 1) { 
                            if (count($banacc)==2) { 
                                mssql_query("UPDATE [lin2db].[dbo].[user_account] SET pay_stat = 0 WHERE (hkey IN (SELECT hkey FROM [lin2db].[dbo].[user_account] WHERE (account IN ('".implode("','",$banacc)."'))))",$MSSQL_CONNECT1); 
                            } else { 
                                mssql_query("UPDATE [lin2db].[dbo].[user_account] SET pay_stat = 0 WHERE (hkey IN (SELECT hkey FROM [lin2db].[dbo].[user_account] WHERE (account IN ('".$userlist[2]."','".$userlist[4]."'))))",$MSSQL_CONNECT1); 
                            } 
                            $log_str .= "Забанены аккаунты: ".implode(", ",$banacc)." со всеми твинками\r\n"; 
                        } elseif ($type2 == 2) { 
                            if (count($banacc)==2) { 
                                mssql_query("UPDATE [lin2db].[dbo].[user_account] SET pay_stat = 0 WHERE (account IN ('".implode("','",$banacc)."'))",$MSSQL_CONNECT1); 
                            } else { 
                                mssql_query("UPDATE [lin2db].[dbo].[user_account] SET pay_stat = 0 WHERE (account IN ('".$userlist[2]."','".$userlist[4]."'))",$MSSQL_CONNECT1); 
                            } 
                            $log_str .= "Забанены аккаунты: ".implode(", ",$banacc)."\r\n"; 
                        } 
                    } 
                } 
            } 
        } 
        $log_str .= "------------------------------------------------------------------\r\n\r\n"; 
    } 
    
    
    @mssql_close($MSSQL_CONNECT); 
    @mssql_close($MSSQL_CONNECT1); 
    
    
    $fp = fopen($cur_dir."\\log\\".date("Y_m_d_H_i_s").".log","w"); 
    fputs($fp,$log_str); 
    fclose($fp); 
    ?> 
    Еще один скриптик:
    Код:
    <?php // дополнительный поиск возможного дюпа (c) gogi79  / 29-04-2010 
    // Актуально, если используется logD, без logD хз будет ли работать. 
    // Нужно создать  в одной директории со скриптом 2 папки: log и tmp туда будут отчеты сваливаться, если будет найден дюп. 
    // Скрипт запускаем каждые 2-3 минуты, по расписанию, рекомендуется не банить скриптом, а только включить отчеты, чтобы проверять вручную. 
    //  Структура запросов в базу сделана в расчете на то, что вы используете защиту авторизации от Hint'а, или переписывайте запросы. 
    // так как поиск твинков для бана ищется по hkey.  
    
    
    $cur_dir = dirname(__FILE__); 
    $dir_err_logs = "E:\\Server\\logd\\log\\err"; // C:\\test\\log\\err 
    $dir_in_logs = "E:\\Server\\logd\\log\\in"; // C:\\test\\log\\in 
    
    
    // тип наказания 
    $array_dup1 = array(); // 1 список - это те, кто скорее всего дюпал 100% 
    $array_dup2 = array(); // 2 список - это те, кто попал до кучи, вероятно среди них дюпер, надо ручками проверять. (редко бывает) 
    // три типа наказания: 
    // 1 = бан всех твинков + kick чаров из игры 
    // 2 = бан только текущего акка + kick чара из игры 
    // 3 = только лог, без банов 
    $type1 = 1; // Наказание для 1 списка 
    $type2 = 3; // Наказание для 2 списка 
    
    
    
    
    // Функции Кэшеда 
    
    
    function tounicode($string) { 
        $rs=""; 
        for($i=0;$i<strlen($string);$i++) { 
            $rs.=$string[$i].chr(0); 
        } 
        return($rs.chr(0).chr(0)); 
    } 
    
    
    function CheckChar($char_id) { 
        $buf=pack("cV",1,$char_id); 
        [email protected]("127.0.0.1","2012",&$errno,&$errstr,5); 
        if ($cachedsocket) { 
            fwrite($cachedsocket,pack("s",(strlen($buf)+2)).$buf); 
            $len=unpack("v",fread($cachedsocket,2)); 
            $rid=unpack("c",fread($cachedsocket,1)); 
            $rs=""; 
            for ($i=0; $i<(($len[1]-4)/4); $i++) { 
                $read=unpack("i",fread($cachedsocket,4)); 
                $rs.=$read[1]; 
            } 
            fclose($cachedsocket); 
            return $rs; 
        } else { 
            return false; 
        } 
    } 
    
    
    function kick_char($id) { 
        [email protected]("127.0.0.1","2012",&$errno,&$errstr,5); 
        if ($cachedsocket) { 
            $buf=pack("c",5); 
            $buf.=pack("i",$id); 
            $buf.=tounicode("admin"); 
            fwrite($cachedsocket,pack("s",(strlen($buf)+2)).$buf); 
            $len=unpack("v",fread($cachedsocket,2)); 
            $rid=unpack("c",fread($cachedsocket,1)); 
            $rs=""; 
            for ($i=0; $i<(($len[1]-4)/4); $i++) { 
                $read=unpack("i",fread($cachedsocket,4)); 
                $rs.=$read[1]; 
            } 
            fclose($cachedsocket); 
            return $rs; 
        } else { 
            return false; 
        } 
    } 
    
    
    function err_log($str) { 
        global $cur_dir; 
        $fp = fopen($cur_dir."\\log\\".date("Y_m_d-H")."_Err.log","a"); 
        fputs($fp, date("H:i:s")." ".$str."\r\n"); 
        fclose($fp); 
    } 
    
    
    function dir_list($dir) { 
        $list = array(); // Массив сортировка по дате модификации файлов 
        if ($handle = opendir($dir)) { 
            while (false !== ($file = readdir($handle))) { 
                if ($file != "." && $file != "..") { 
                    $list[$file] = filemtime($dir."\\".$file); 
                } 
            } 
            closedir($handle); 
        } else { 
            return false; 
        } 
        if (count($list)>0) { 
            arsort($list); 
            return $list; 
        } 
        return false; 
    } 
    
    
    // Поиск Already send list. в Err server логе 
    $err_files = dir_list($dir_err_logs); 
    if ($err_files === false) { 
        die(); 
    } 
    
    
    $lastfile = null; 
    foreach ($err_files as $filename => $lastmod) { 
        if (strpos($filename,"-server-") !== false) { 
            $lastfile = $filename; 
            break; 
        } 
    } 
    if (!$lastfile) { 
        die(); 
    } 
    
    
    $fp = fopen($dir_err_logs."\\".$lastfile,"r"); 
    $errfarr = array(); 
    while (!feof($fp)) { 
        $line = fgets($fp); 
        // Дюп InvalidAdena 
        // 11/21/2009 20:42:49.781, Already send list. 
        if (strpos($line,"Already send list.") !== false) { 
            if (preg_match("~^(([0-9]{2})/([0-9]{2})/([0-9]{4}) ([0-9]{2}):([0-9]{2}):([0-9]{2})\.[0-9]{1,4}), ~",$line,$match)) { 
                $fulltimestr = $match[1]; 
                $timestamp = mktime(intval($match[5]), intval($match[6]), intval($match[7]), intval($match[2]), intval($match[3]), $match[4]); 
                $errfarr[$fulltimestr] = $timestamp; 
            } 
        } 
    } 
    fclose($fp); 
    
    
    // Проверяем массив, есть ли нахождения Already send list в текущем логе. 
    $counterr = count($errfarr); 
    if ($counterr<1) die(); // ничего нет, завершаем работу. 
    
    
    //print_r($errfarr); 
    
    
    // Проверяем кэш файл на наличие совпадений, если он есть 
    $cachearr = array(); 
    if (file_exists($cur_dir."\\tmp\\err_".date("Ymd").".txt")) { 
        $f = file($cur_dir."\\tmp\\err_".date("Ymd").".txt"); 
        for ($i=0;$i<count($f);$i++) { 
            $cachearr[rtrim($f[$i])] = 1; 
        } 
    } 
    
    
    $newerr = array(); 
    foreach ($errfarr as $tstr => $tstamp) { 
        if (isset($cachearr[$tstr])) continue; 
        $newerr[$tstr] = $tstamp; 
    } 
    if (count($newerr)<1) die(); // нет новых ошибок, завершаем работу. 
    
    
    // DB Game Server 
    $MSSQL_CONNECT = mssql_connect("localhost","sa","pass"); 
    if (!$MSSQL_CONNECT) { 
        @mssql_close($MSSQL_CONNECT); 
        die(); 
    } 
    
    
    // DB Login Server 
    $MSSQL_CONNECT1 = mssql_connect("sql.bestworld.ru","sa","pass"); 
    if (!$MSSQL_CONNECT1) { 
        @mssql_close($MSSQL_CONNECT1); 
        die(); 
    } 
    
    
    // Лог server IN 
    $in_files = dir_list($dir_in_logs); 
    if ($in_files === false) { 
        die(); 
    } 
    $errmodmax = max($newerr); 
    $logfile = null; 
    foreach ($in_files as $filename => $lastmod) { 
        if (strpos($filename,"-server-") !== false) { 
            if ($errmodmax <= $lastmod) { 
                $logfile = $filename; 
            } 
        } 
    } 
    if (!$logfile) { 
        err_log("Не смог найти файл server IN лога (".$errmodmax.")"); 
        die(); 
    } 
    
    
    // Читаем server IN лог, поиск Action 916 =+- 0 sec 
    $fp = fopen($dir_in_logs."\\".$logfile,"r"); 
    if ($fp) { 
        $fp2 = fopen($cur_dir."\\tmp\\err_".date("Ymd").".txt","w"); 
        foreach ($newerr as $tstr => $tstamp) { // 12/29/2008 15:30:00.281 
            $curtimestr = date("m/d/Y H:i:s.", $tstamp); 
            $orig_time = $tstr; // приоритетное время, равно событию, если найдем совпадения в этом времени, тогда используем его. 
            $tmpstr = array(); // временные строки 
            $tmpstr2 = array(); // временные строки 
            $priorfound = false; 
            $priorfound2 = false; 
            $j=0; 
            $m=0; 
            if (rewind($fp)===false) { 
                err_log("Курсор не установлен в начало файла (".$dir_in_logs."\\".$logfile.")"); // на всякий... 
                continue; 
            } 
            fputs($fp2,$tstr."\n"); // запись в кэш 
            while (!feof($fp)) { 
                $line = fgets($fp); 
                if (strpos($line,$curtimestr) !== false) { 
                    if (strpos($line,", 916,") !== false) { 
                        $tmpstr[$j] = $line; 
                        if (strpos($line,$orig_time) !== false) { 
                            // приоритетное время 
                            $priorfound = $j; 
                        } 
                        $j++; 
                    } elseif (strpos($line,", 869,") !== false) { 
                        $tmpstr2[$m] = $line; 
                        if (strpos($line,$orig_time) !== false) { 
                            // приоритетное время 
                            $priorfound2 = $m; 
                        } 
                        $m++; 
                    } 
                } 
            } 
            // Ищем 916 
            $counttmpstr = count($tmpstr); 
            if ($counttmpstr<1) { 
                // никуя не найдено, так тоже бывает... знач не судьба или ошибка (это не тот дюп) 
                if (count($tmpstr2)>0) { 
                    err_log("Однозначно дюп! act 869 (".$dir_in_logs."\\".$logfile.") время в cached-err - ".$tstr.""); 
                } else { 
                    err_log("Возможно дюп другого типа (".$dir_in_logs."\\".$logfile.") время в cached-err - ".$tstr.""); 
                     
                } 
                continue; 
            } 
            // Если найдено приоритетное время, смотрим лог в этом времени и до этого времени. 
            $dupfound = array(); // массив с записями 916 которые находились в приоритетном времени 
            $oldfound = array(); // массив с записями 916 в другое время (если нет записей в $dupfound, банить будем этих) 
            if ($priorfound!==false) { 
                for ($i=$priorfound;$i>=0;$i--) { 
                    $exp = explode(",",$tmpstr[$i]); 
                    if ($exp[0] == $orig_time) { 
                        $dupfound[] = array($exp[0],$exp[22],$exp[23],$exp[24],$exp[25]); 
                    } else { 
                        $oldfound[] = array($exp[0],$exp[22],$exp[23],$exp[24],$exp[25]); 
                    } 
                } 
            } else { // если не найдено приоритетное время, пишем всех 
                foreach ($tmpstr as $val) { 
                    $exp = explode(",",$val); 
                    $oldfound[] = array($exp[0],$exp[22],$exp[23],$exp[24],$exp[25]); 
                } 
            } 
            // Расстановка записей по типам 
            if (count($dupfound)>0) { 
                $array_dup1[$tstr] = $dupfound; 
            } 
            if (count($oldfound)>0) { 
                $array_dup2[$tstr] = $oldfound; 
            } 
        } 
        fclose($fp); 
        fclose($fp2); 
    } else { 
        err_log("Не смог открыть файл (".$dir_in_logs."\\".$logfile.")"); 
    } 
    
    
    //print_r($array_dup1); 
    //print_r($array_dup2); 
    
    
    // Часть вторая, наказание и отчеты :P 
    $log_str = ""; 
    $ban_cnt = 0; 
    foreach ($newerr as $duptime => $val) { 
        $log_str .= "Ахтунг! Обнаружен дюп, время - $duptime\r\n------------------------------------------------------------------\r\n"; 
        if (is_array($array_dup1[$duptime])) { 
            $log_str .= "Найдены основные подозреваемые:\r\n"; 
            $ban_cnt++; 
            foreach ($array_dup1[$duptime] as $userlist) { 
                $log_str .= $userlist[0]." / ".$userlist[1].":".$userlist[2]." - ".$userlist[3].":".$userlist[4]."\r\n"; 
                // Ищем в базе 
                if ($MSSQL_CONNECT && $MSSQL_CONNECT1) { 
                    if ($type1 == 1 || $type1 == 2) { 
                        $banacc = array(); 
                        $sql = mssql_query("SELECT char_id, char_name, account_name FROM [lin2world].[dbo].[user_data] WHERE char_name IN ('".$userlist[1]."','".$userlist[3]."')",$MSSQL_CONNECT); 
                        if (mssql_num_rows($sql)>0) { 
                            while (list($char_id,$char_name,$account_name) = mssql_fetch_row($sql)) { 
                                $CheckChar = CheckChar($char_id); 
                                if ($CheckChar === false) { 
                                    kick_char($char_id); 
                                    sleep(1); 
                                } 
                                kick_char($char_id); 
                                $banacc[] = $account_name; 
                            } 
                        } 
                        if ($type1 == 1) { 
                            // Бан аккаунтов + твинки 
                            if (count($banacc)>0) { 
                                $sql2 = mssql_query("SELECT account FROM [lin2db].[dbo].[hauthd_log] WHERE (hkey IN (SELECT DISTINCT hkey FROM [lin2db].[dbo].[hauthd_log] WHERE (account IN ('".implode("','",$banacc)."')) AND (DATEDIFF(SECOND, [time], GETDATE()) < 86400 * 3))) GROUP BY account",$MSSQL_CONNECT1); 
                                if (mssql_num_rows($sql2)>0) { 
                                    $twinks = array(); 
                                    while (list($tw_account) = mssql_fetch_row($sql2)) { 
                                        $twinks[] = $tw_account; 
                                    } 
                                    if (count($twinks)>0) { 
                                        mssql_query("UPDATE [lin2db].[dbo].[user_account] SET pay_stat = 0 WHERE (account IN ('".implode("','",$twinks)."'))",$MSSQL_CONNECT1); 
                                        //echo "UPDATE [lin2db].[dbo].[user_account] SET pay_stat = 0 WHERE (account IN ('".implode("','",$twinks)."'))\r\n"; 
                                    } 
                                } 
                            } 
                            $log_str .= "Забанены аккаунты с твинками: ".implode(", ",$twinks)."\r\n"; 
                        } elseif ($type1 == 2) { 
                            if (count($banacc)>0) { 
                                mssql_query("UPDATE [lin2db].[dbo].[user_account] SET pay_stat = 0 WHERE (account IN ('".implode("','",$banacc)."'))",$MSSQL_CONNECT1); 
                            } 
                            $log_str .= "Забанены аккаунты: ".implode(", ",$banacc)."\r\n"; 
                        } 
                    } 
                } 
            } 
        } 
        if (is_array($array_dup2[$duptime])) { 
            $log_str .= "Найдены другие подозреваемые:\r\n"; 
            $ban_cnt++; 
            foreach ($array_dup2[$duptime] as $userlist) { 
                $log_str .= $userlist[0]." / ".$userlist[1].":".$userlist[2]." - ".$userlist[3].":".$userlist[4]."\r\n"; 
                // Ищем в базе 
                if ($MSSQL_CONNECT && $MSSQL_CONNECT1) { 
                    if ($type2 == 1 || $type2 == 2) { 
                        $banacc = array(); 
                        $sql = mssql_query("SELECT char_id, char_name, account_name FROM [lin2world].[dbo].[user_data] WHERE char_name IN ('".$userlist[1]."','".$userlist[3]."')",$MSSQL_CONNECT); 
                        if (mssql_num_rows($sql)>0) { 
                            while (list($char_id,$char_name,$account_name) = mssql_fetch_row($sql)) { 
                                $CheckChar = CheckChar($char_id); 
                                if ($CheckChar === false) { 
                                    kick_char($char_id); 
                                    sleep(1); 
                                } 
                                kick_char($char_id); 
                                $banacc[] = $account_name; 
                            } 
                        } 
                        if ($type2 == 1) { 
                            // Бан аккаунтов + твинки 
                            if (count($banacc)>0) { 
                                $sql2 = mssql_query("SELECT account FROM [lin2db].[dbo].[hauthd_log] WHERE (hkey IN (SELECT DISTINCT hkey FROM [lin2db].[dbo].[hauthd_log] WHERE (account IN ('".implode("','",$banacc)."')) AND (DATEDIFF(SECOND, [time], GETDATE()) < 86400 * 3))) GROUP BY account",$MSSQL_CONNECT1); 
                                if (mssql_num_rows($sql2)>0) { 
                                    $twinks = array(); 
                                    while (list($tw_account) = mssql_fetch_row($sql2)) { 
                                        $twinks[] = $tw_account; 
                                    } 
                                    if (count($twinks)>0) { 
                                        mssql_query("UPDATE [lin2db].[dbo].[user_account] SET pay_stat = 0 WHERE (account IN ('".implode("','",$twinks)."'))",$MSSQL_CONNECT1); 
                                        //echo "UPDATE [lin2db].[dbo].[user_account] SET pay_stat = 0 WHERE (account IN ('".implode("','",$twinks)."'))\r\n"; 
                                    } 
                                } 
                            } 
                            $log_str .= "Забанены аккаунты с твинками: ".implode(", ",$twinks)."\r\n"; 
                        } elseif ($type2 == 2) { 
                            if (count($banacc)>0) { 
                                mssql_query("UPDATE [lin2db].[dbo].[user_account] SET pay_stat = 0 WHERE (account IN ('".implode("','",$banacc)."'))",$MSSQL_CONNECT1); 
                            } 
                            $log_str .= "Забанены аккаунты: ".implode(", ",$banacc)."\r\n"; 
                        } 
                    } 
                } 
            } 
        } 
        $log_str .= "------------------------------------------------------------------\r\n\r\n"; 
    } 
    
    
    @mssql_close($MSSQL_CONNECT); 
    @mssql_close($MSSQL_CONNECT1); 
    
    
    if ($ban_cnt>0) { 
        $fp = fopen($cur_dir."\\log\\".date("Y_m_d_H_i_s").".log","w"); 
        fputs($fp,$log_str); 
        fclose($fp); 
    } 
    
    
    ?>