myDC.ru

Здравствуйте, гость ( Вход | Регистрация )

 
5 страниц V  « < 3 4 5  
Ответить в данную темуНачать новую тему

> Хаблисты

Enyby
сообщение 20.8.2010, 1:38
Сообщение #81


Освоившийся участник
*****

Группа: Пользователи
Сообщений: 391
Регистрация: 4.11.2009
Из: Дом
Пользователь №: 4 923
Спасибо сказали: 239 раз




Пингом - быстрей, но пинг предоставляет недостаточно информации. С другой стороны, он виден админу, и если часто пинговать, то вас попросту забанят. Поэтому у меня раз в 5 минут хаблист заходит как клиент и раз в час - как пингер, т. е. каждый 12 раз из тех, что по 5 минут.

В целом пингер неплох.
Критика по коду:
  1. Соблюдайте отступы, намного приятнее будет читать. Для этих целей лучше пользоваться IDE с автоформатированием кода, например, Eclipse.
  2. Лучше не использовать принудительное подавление @, а писать так, чтобы никаких ошибок не было.
  3. Код
    $myinfo = explode('$', $linie[$i]);
    @$share = $share + $myinfo[6];

    У вас нет никаких гарантий что в массиве 6 элементов. Целесобразнее:
    Код
    $myinfo = explode('$', $linie[$i]);
    if(isset($myinfo[6]))
    $share = $share + $myinfo[6];

  4. Код
    $useri = $useri + 1;

    Лучше писать через оператор ++.
  5. Код
    function lock2key($_LOCK, $port)

    Не тот алгоритм. Этот алгоритм для захода ХАБА на хаблист, а вам нужен обычный, в котором не порта. Да и порт вы не тот указали, вы указали порт подключения, а в этом алгоритме нужно указать локальный порт.


Чтобы бота пускали на все хабы, не нужно передавать специфический тэг клиента. Да и число хабов онлайн можно не 21 ставить. "H:21/0/1" - 21 хаб 1 и на одном админ.

UPD:
И да, я тут увидел зачатки работы как клиента (Подсчет MyINFO). Вам предстоит нетривиальная задача определения когда заканчивается процесс инициализации хаба. Также вам необходимо отсевать свой собственный MyINFO, так как он вносит погрешность в ваши измерения. В дополнение к этому есть скрипты манипулирующие MyINFO, из-за них оно может приходить несколько раз для одного пользователя, что вызовет искажение размера шары и числа пользователей.

Так что работы тут еще много.


Спасибо сказали:
Go to the top of the page
+Quote Post
PomanoB
сообщение 20.8.2010, 9:03
Сообщение #82


AmxModx Scripter
*****

Группа: Пользователи
Сообщений: 302
Регистрация: 2.12.2008
Из: Королев
Пользователь №: 1 283
Спасибо сказали: 127 раз




Можно считать, что процесс инициализации закончился, если команды MyINFO уже были, и пришла первая не MyINFO команда


Спасибо сказали:
Go to the top of the page
+Quote Post
dro
сообщение 20.8.2010, 12:13
Сообщение #83


Начинающий
*

Группа: Пользователи
Сообщений: 13
Регистрация: 16.8.2010
Пользователь №: 7 500
Спасибо сказали: 0 раз




2Enyby Спасибо за критику и советы. Lock поправил

По поводу MyINFO можно поидеи себя отсеять сделав -1 (+- 2 чел не сыграют роли)
Так же можно сделать и с шарой.
Но вот Вы правильно заметили что может придти несколько раз MyINFO, на этот счет я думаю загонять все данные в массив и потом массив проверять на одинакове эл-ты, а далее уже из этого массива и будем считать шару и число юзеров за вычетом моих данных. Верно ли это?

Бывает такое что хаб после MyINFO рвет соединение и скрипт отработал впустую, например dc.cifracom.ru

Собственно по какому принципу лучше смотреть когда заканчивается процесс инициализации хаба?
Go to the top of the page
+Quote Post
Enyby
сообщение 20.8.2010, 13:00
Сообщение #84


Освоившийся участник
*****

Группа: Пользователи
Сообщений: 391
Регистрация: 4.11.2009
Из: Дом
Пользователь №: 4 923
Спасибо сказали: 239 раз




Итак, по порядку.

Как было справделиво замеченно, можно отсекать по команде не MyINFO, после MyINFO, но не все тут гладко.
Можно довольно долго висеть на хабе из 5 человек ожидая другой команды.

Вообще говоря, по протоколу, список MyINFO, должен заканчиваться MyINFO хаблиста, но, к сожалению, так поступают не все хабы.

Дальше. Есть такое расширение протокола как Zon. Которое предполагает сжатие gzip дл передаваемых данных. проблема состоит в том, что некоторые хабы в любом случае включат это сжатие не смотря поддерживается оно клиентом или нет. Эта команда может появляться где угодно и, обычно, список пользователей передается в сжатом виде, что означает, что ее нужно игнорировать и не разрывать соединение, так как процесс входа на хаб может быть не завершен.

Также следует отслеживать команды ValidateDenide и ForceMove. Первая означает что ник занят или не является допустимым, а вторая - дает редирект, при переполнении или других причинах. Четкой команды, свидетельствующей о бане не существует, обычно это сообщение от бота со словом ban, но не обязательно.

100% алгоритма определения окончания инициализации не существует или мне он не известен. Пользуюсь набором правил следующего вида:
  1. Если получены команды Quit или Search - вход завершен.
  2. Если получена команда OpList и перед этим была получена хоть одна команда MyINFO - вход завершен. Некоторые хабы, отсылают список операторов ранее списка пользователей, хотя это и не соответствует протоколу.
  3. Если было зафиксировано получение команд MyINFO, а после этого пришла команда не Zon и не MyINFO - вход завершен.


Как вариант, можно еще пытаться отлавливать MOTD, но оно может отсылаться в ЛС.

По поводу дубликатов, проблема решается просто, все это дело заноситься в ассциативный массив по ключу ника, а потом из массива и считается шара и число пользователей. Также необходимо отслеживать свой ник и его игнорировать.

Еще. Хаб может не поддерживать BotINFO/HubINFO, тогда с текущим алгоритмом вы будете ждать вечность команды HubINFO. Чтобы этого не произошло, необходимо, после указания поддержки данных команд в отсылаемом Supports, проверить наличие поддержи в полученном Supports.


Спасибо сказали:
Go to the top of the page
+Quote Post
dro
сообщение 20.8.2010, 13:38
Сообщение #85


Начинающий
*

Группа: Пользователи
Сообщений: 13
Регистрация: 16.8.2010
Пользователь №: 7 500
Спасибо сказали: 0 раз




С шарой и ассоциативным массивом я так и сделал.
А насчет остального буду думать и дописывать спасибо!!!!!
Go to the top of the page
+Quote Post
Alexey
сообщение 20.8.2010, 15:44
Сообщение #86


7 квадратиков
*******

Группа: Модераторы
Сообщений: 793
Регистрация: 21.1.2009
Пользователь №: 1 895
Спасибо сказали: 301 раз




Цитата(Enyby @ 20.8.2010, 14:00) *
[*]Если получена команда OpList и перед этим была получена хоть одна команда MyINFO - вход завершен. Некоторые хабы, отсылают список операторов ранее списка пользователей, хотя это и не соответствует протоколу.

В одном хабе с самописным сервером выполнение этого условия вызовет преждевременный разрыв, поскольку отсылается такая порнография:
Раскрывающийся текст
http://dchublist.ru/hubs/1975/
Цитата
Hub: [Incoming][193.93.13.15:411] $OpList CheByRashKa$$Eras$$
Hub: [Incoming][193.93.13.15:411] $MyINFO $ALL -=SS=- <StrgDC++ V:2.21,M:A,H:8/1/0,S:18>$ $0.005$$13535451665$
Hub: [Incoming][193.93.13.15:411] $OpList CheByRashKa$$Eras$$
Hub: [Incoming][193.93.13.15:411] $MyINFO $ALL Alex_ [5]<ApexDC++ V:s16.4,M:P,H:4/0/0,S:5>$ $0.01 $ $18657570984$
Hub: [Incoming][193.93.13.15:411] $OpList CheByRashKa$$Eras$$
Hub: [Incoming][193.93.13.15:411] $MyINFO $ALL -<pl++ V:4.56,M:A,H:5/0/0,S:10>$ $100$http://10.5.0.1/support/ $28861738685$
Hub: [Incoming][193.93.13.15:411] $OpList CheByRashKa$$Eras$$
Hub: [Incoming][193.93.13.15:411] $MyINFO $ALL Nafanya 3DCar.ru<StrgDC++ V:2.41,M:A,H:5/0/0,S:5>$ $100$http://10.5.0.1/forum/$313242599709$
Hub: [Incoming][193.93.13.15:411] $OpList CheByRashKa$$Eras$$


Спасибо сказали:
Go to the top of the page
+Quote Post
Enyby
сообщение 20.8.2010, 15:58
Сообщение #87


Освоившийся участник
*****

Группа: Пользователи
Сообщений: 391
Регистрация: 4.11.2009
Из: Дом
Пользователь №: 4 923
Спасибо сказали: 239 раз




Спасибо за замечание. Мне оно правда не грозит, так как хаблист локальный, но буду знать.
Вообще говоря, самописные хабы это страшная сила, наподобие IE 6 при верстке. У меня были проблемы с dcworlds, но он уже не локальный, да и давно уже это было, не помню сути. Помню только что нарушался протокол и хаб был самописным.
Go to the top of the page
+Quote Post
dro
сообщение 29.8.2010, 15:25
Сообщение #88


Начинающий
*

Группа: Пользователи
Сообщений: 13
Регистрация: 16.8.2010
Пользователь №: 7 500
Спасибо сказали: 0 раз




А подскажите такой момент.
У меня кол-во пользователей с действительным расходится примерно на 100.
Где искать косяк?
Или это из-за того что не все клиенты сразу отвечают на MyInfo? И как быть тогда?
Go to the top of the page
+Quote Post
Enyby
сообщение 29.8.2010, 16:08
Сообщение #89


Освоившийся участник
*****

Группа: Пользователи
Сообщений: 391
Регистрация: 4.11.2009
Из: Дом
Пользователь №: 4 923
Спасибо сказали: 239 раз




1. Включаешь вывод всех входящих/отправленных команд и получаешь лог файл.
2. В отладчике ДС клиента заходишь на тот же хаб - получаешь второй лог.
3. Ищешь отличия. Чтобы не делать это руками, организуй вывод со своего хаблиста в формат аналогичный отладчику, а потом пользуйся утилитами сравнения файлов, например, тем же тоталом коммандером.
4. Если отличия есть, то причина в том что ты рано закрыл соединение.
5. Если нет, то причина в обработке внутри пингера - начинаешь во всю использовать print_r и var_dump.

UPD: И да, на майинфо отвечает не клиент а хаб. И отсылает он сразу все, вот только иногда он это криво делает.
Go to the top of the page
+Quote Post
PomanoB
сообщение 29.8.2010, 17:23
Сообщение #90


AmxModx Scripter
*****

Группа: Пользователи
Сообщений: 302
Регистрация: 2.12.2008
Из: Королев
Пользователь №: 1 283
Спасибо сказали: 127 раз




Причина может быть в том, что у тебя в цикле читаются данные из сокета, потом эти данные разбиваются по |.
Когда данных пришло меньше, чем 2048, все хорошо.
Но когда хаб большой, все MyINFO за одно чтение получить не удается, и выходит, что из сокета прочиталось часть MyINFO, то есть конец буфера выглядит так: "... |$MyINF". И остальная часть MyINFO прочитается только при следующем чтении. Но увеличиваться счетчик юзеров не будет, так как первая часть MyINFO не распознается как MyINFO.


Спасибо сказали:
Go to the top of the page
+Quote Post
Enyby
сообщение 29.8.2010, 18:30
Сообщение #91


Освоившийся участник
*****

Группа: Пользователи
Сообщений: 391
Регистрация: 4.11.2009
Из: Дом
Пользователь №: 4 923
Спасибо сказали: 239 раз




PomanoB прав. Чтобы подобного не возникало, нужно последний элемент всегда приплюсовывать к новому буферу, например так:
Код
        while ($buffer = socket_read($socket, 2048, PHP_BINARY_READ)) {
            $linie = explode('|', $end.$buffer);
            $size = sizeof($linie);
            for ($i = 0; $i < $size; ++$i) {
                if ($i + 1 == $size) {
                    $end = $linie[$i];
                    break;
                }

Если элемент последний, то он заносится в переменную $end, которая затем приписывается спереди к новому буферу.

UPD: На самом деле не важно где прервалсь команда, на ключевом слове или где-то еще, в любом случае дальнейшая обработка фрагмента будет ошибочной.


Спасибо сказали:
Go to the top of the page
+Quote Post
Nickolya
сообщение 29.8.2010, 19:01
Сообщение #92


Главный ра******й тут...
*********

Группа: Главные администраторы
Сообщений: 1 727
Регистрация: 18.5.2008
Из: RF, 2la
Пользователь №: 1
Спасибо сказали: 776 раз




Да, но прибавлять последний элемент массива надо лишь при условии что он не заканчивается |, иначе получится дубляж некоторых команд, что конечно может и не быть критичным, но все-таки неверно. Хотя как я тут вижу, если команды были полными, то приплюсуется лишь пустая строка big_smile.gif
Go to the top of the page
+Quote Post
Enyby
сообщение 29.8.2010, 19:05
Сообщение #93


Освоившийся участник
*****

Группа: Пользователи
Сообщений: 391
Регистрация: 4.11.2009
Из: Дом
Пользователь №: 4 923
Спасибо сказали: 239 раз




Последний элемент не может заканчиваться символом "|", так как функция explode разбивает по нему на элементы массива. Если же "|" будет последним символом в строке, то в массиве последний элемент будет пустой строкой.
Go to the top of the page
+Quote Post
dro
сообщение 29.8.2010, 21:02
Сообщение #94


Начинающий
*

Группа: Пользователи
Сообщений: 13
Регистрация: 16.8.2010
Пользователь №: 7 500
Спасибо сказали: 0 раз




Частично понял о чем речь!
Спасибо буду дальше разбираться

З.Ы. А если размер буффера поставить больше?


UPD: Вроде бы все стало считать отдично!!! Благодарю Вас!
Go to the top of the page
+Quote Post
Enyby
сообщение 29.8.2010, 22:04
Сообщение #95


Освоившийся участник
*****

Группа: Пользователи
Сообщений: 391
Регистрация: 4.11.2009
Из: Дом
Пользователь №: 4 923
Спасибо сказали: 239 раз




Цитата(dro @ 29.8.2010, 20:02) *
А если размер буффера поставить больше?

Возврат из функции socket_read происходит по двум причинам:
  1. заполнился буфер;
  2. превышено время ожидания заполнения буфера;

Если буфер слишком мал, то скрипт будет частенько бегать в цикле, не обрабатывая команды, а лишь инкрементно приращая переменную $end. Если же буфер слишком велик, то большую часть времени скрипт будет ждать таймаута заполнения буфера, в результате чего, хаб имеет право разорвать соединение, как слишком медленное, но даже если этого не произойдет, все равно будет существенное падение скорости работы пингера.


Спасибо сказали:
Go to the top of the page
+Quote Post
dro
сообщение 29.8.2010, 22:48
Сообщение #96


Начинающий
*

Группа: Пользователи
Сообщений: 13
Регистрация: 16.8.2010
Пользователь №: 7 500
Спасибо сказали: 0 раз




Я понял. Спасибо.

Если вас не затруднит, откритикуйте мой пингер
Код
Код
<?php

set_time_limit ( 1800 );
require ('config.php');

#####timer
      $mtime = microtime();
      $mtime = explode(' ', $mtime);
      $mtime = $mtime[1] + $mtime[0];
      $starttime = $mtime;
#########

function debug($text){
    $name = 'log_'.date('H:m d-m').'.txt';
    $filename = 'log/'.$name;
    $handle = fopen($filename, 'a');
    fwrite($handle, $text);
    fclose($handle);    
}
      
function execute($sock, $str) {
      #echo "A: ".$str.'|'.PHP_EOL."<br>";

    $dedubg_info="A: ".$str."|".PHP_EOL."\r\n";
    debug($dedubg_info);

    socket_send($sock, $str.'|', strlen($str) + 1, NULL);
}

function lock2key($_LOCK) {

    $lockLength = strlen ($_LOCK);

    $h = ord($_LOCK{0}) ^ ord( $_LOCK{ $lockLength - 1} ) ^ ord( $_LOCK{ $lockLength - 2} ) ^ 5;
    while ($h > 255) {$h = $h - 256;}

    $h = (($h<<4) & 240) | (($h>>4) & 15);

    $a = $h;

    if ($a == '126' || // '~'
    $a == '124' || // '|'
    $a == '96' || // '`'
    $a == '36' || // '$'
    $a == '5' || // '^E'
    $a == '0') // NUL
    {
        $LockToKey = "/%DCN";

        if ($a < 100)
        $LockToKey .="0";
        if ($a < 10)
        $LockToKey .="0";
        $LockToKey .= $a;
        $LockToKey .= "%/";
    } else {
        $LockToKey = chr ($a);
    }

    for ($j = 1; $j < strlen($_LOCK); $j++) {
        $h = ord($_LOCK{$j}) ^ ord($_LOCK{$j-1});

        while ($h > 255) {$h = $h - 256;}

        $h = (($h<<4) & 240) | (($h>>4) & 15);
        $a = $h;

        if ($a == '126' || // '~'
        $a == '124' || // '|'
        $a == '96' || // '`'
        $a == '36' || // '$'
        $a == '5' || // '^E'
        $a == '0') // NUL
        {
            $LockToKey .= "/%DCN";

            if ($a < 100)
            $LockToKey .="0";
            if ($a < 10)
            $LockToKey .="0";
            $LockToKey .= $a;
            $LockToKey .= "%/";
        } else {
            $LockToKey .= chr ($a);
        }
    }

    return $LockToKey;
}

$mysql = mysql_connect($host, $user, $userpass) or die("<font color='red'>Ошибка соединения с MySQL!</font><br>");
mysql_select_db($bd, $mysql) or die("<font color='red'>Ошибка базы данных MySQL!</font><br>");

mysql_query("SET NAMES 'cp1251'");
mysql_query("SET CHARACTER SET 'cp1251'");

    $result = @mysql_query("SELECT * FROM `".$dbtable."` ORDER BY `".$dbtable."`.`ID` ASC LIMIT 0 , 30");
     while ($data = @mysql_fetch_assoc($result)) {

        $total_share= 0;
        $useri = 0;
        $infoyes = 1;
        $info='';
        $end = '';

    if ($fp=@fsockopen($data['Adres'],$data['Port'],$ERROR_NO,$ERROR_STR,5)) {
        fclose($fp);
        $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
        if (!socket_connect($socket, $data['Adres'], $data['Port'])) {
            echo 'Error..';
            return;
        }

    echo "Starting ".$data['Adres']."<br>";

    while ($buffer = socket_read($socket, 2048, PHP_BINARY_READ)) {
            $linie = explode('|', $end.$buffer);
            $size = sizeof($linie);
            for ($i = 0; $i < $size; ++$i) {
                if ($i + 1 == $size) {
                    $end = $linie[$i];
                    break;
                }

         $user = explode(' ', $linie[$i]);

    #echo "Q: ".$linie[$i].PHP_EOL."<br>";

    $dedubg_info="Q: ".$linie[$i].PHP_EOL."\r\n";
    debug($dedubg_info);

            if(preg_match('#не поддерживает пинга#',$linie[$i])){
                echo $data['Adres']." не поддерживает пинга<br>";
                $info=0;
                break;
            }else{
                switch($user[0]) {
                case '$Lock':
                    execute($socket, '$Supports NoGetINFO NoHello UserIP2 Feed MCTo HubTopic ClientID MiniSlots GetZBlock ADCGet CHUNK GetCID BotINFO');
                    execute($socket, '$Key '.lock2key($user[1],$data['Port']));
                    execute($socket, '$ValidateNick '.$nick);
                break;
                case '$Hello':
                    if ($user[1] == $nick) {
                    execute($socket, '$Version 1,0091');
                    execute($socket, '$GetNickList');
                    execute($socket, '$MyINFO $ALL '.$nick.' Bot by dro <++ V:0.674,M:A,H:1/0/1,S:20>$ $LAN(T3).$alexandr@drozdin.ru$'.$myshare.'$');
                    #execute($socket, '$MyINFO $ALL '.$nick.' Bot by dro <FlylinkDC++ V:(r386),M:P,H:1/0/1,S:15>$ $100    $alexandr@drozdin.ru$670969607454$');
                    execute($socket, '$BotINFO {HubListPinger} hublist pinger');
                    }
                break;
                        case '$HubName':
                       $hubname = explode(' ', $linie[$i], 2);
                               $tmp = explode(' - ', $hubname[1], 2);
                                $hubname = $tmp[0];                                        
                       break;
                case '$HubINFO':
                    $hubinfo = $linie[$i];
                    break 3;
                break;
                case '$MyINFO':
                    $myinfo = explode('$', $linie[$i]);
                    if(isset($myinfo[6])){
                        $info[$myinfo[2]]= $myinfo[6];
                    }
                break;
                }
            }
        }
    }
    socket_close($socket);
    echo "End ".$data['Adres']."<br>";    
            
    $hubinfo = str_replace( "HubINFO ", "", $hubinfo);
    $hubinfo = explode('$', $hubinfo);
    $hubinfo[3] = str_replace(".px.", " ", $hubinfo[3]);

    $hubinfo[1] = str_replace("<", "<", $hubinfo[1]);
    $hubinfo[1] = str_replace(">", ">", $hubinfo[1]);
    $hubinfo[3] = str_replace("<", "<", $hubinfo[3]);
    $hubinfo[3] = str_replace(">", ">", $hubinfo[3]);
    
    if($hubinfo[1] == ''){
        $hubinfo[1] = $hubname;
        $hubinfo[3] = "Неудалось получить информацию о хабе";
    }
    
    if($info!=0){
        array_unique($info);
        $useri=count($info);
        $total_share=0;
        
        foreach($info as $share){
            $total_share=$share+$total_share;
        }
        $total_share=$total_share - $myshare;
    }else{
        $hubinfo[1] = $data['Adres'];
        $hubinfo[3] = "Возможно хаб не поддерживает пинги";
    }
    #print_r($info);
    unset($info);

    if ($infoyes == "1") {
        // mysql_query("UPDATE `".$dbtable."` SET Name = '".$hubinfo[1]."', Descr = '".$hubinfo[3]."',
                     // Maxusers = '".$hubinfo[4]."', MinShare = '".$hubinfo[5]."', MinSlots = '".$hubinfo[6]."',
                     // MaxHubs = '".$hubinfo[7]."', Soft = '".$hubinfo[8]."'  WHERE id = ".$data['ID']."");

        mysql_query("UPDATE `".$dbtable."` SET Name = '".$hubinfo[1]."',Descr = '".$hubinfo[3]."',
                     Maxusers = '".$hubinfo[4]."', MinShare = '".$hubinfo[5]."', MinSlots = '".$hubinfo[6]."',
                     MaxHubs = '".$hubinfo[7]."', Soft = '".$hubinfo[8]."'  WHERE id = ".$data['ID']."");
    }
    #$infoyes = "0";

    mysql_query("UPDATE `".$dbtable."` SET Users = ".$useri.", Status = 'Online', Share = ".floatval($total_share)." WHERE id = ".$data['ID']."");

    if ($useri > $data['Userspeak']){
        mysql_query("UPDATE `".$dbtable."` SET Userspeak = ".$useri." WHERE id = ".$data['ID']."");
    }

    if ($total_share > $data['Sharepeak']){
        mysql_query("UPDATE `".$dbtable."` SET Sharepeak = ".floatval($total_share)." WHERE id = ".$data['ID']."");
    }
    
}else{
    mysql_query("UPDATE `".$dbtable."` SET Status = 'Offline' WHERE id = ".$data['ID']."");
    mysql_query("UPDATE `".$dbtable."` SET Users = '0' WHERE id = ".$data['ID']."");
    mysql_query("UPDATE `".$dbtable."` SET Share = '0' WHERE id = ".$data['ID']."");
    }
}
mysql_query("UPDATE `lastupdate` set `time` = now()");
mysql_close($mysql);
########end timer
      $mtime = microtime();
      $mtime = explode(" ", $mtime);
      $mtime = $mtime[1] + $mtime[0];
      $endtime = $mtime;
      $totaltime = ($endtime - $starttime);
      echo 'This page was created in ' .$totaltime. ' seconds.';


?>


Сообщение отредактировал Saymon - 29.8.2010, 22:59
Причина редактирования: Такой большой код лучше прятать под спойлер!
Go to the top of the page
+Quote Post
Enyby
сообщение 30.8.2010, 7:50
Сообщение #97


Освоившийся участник
*****

Группа: Пользователи
Сообщений: 391
Регистрация: 4.11.2009
Из: Дом
Пользователь №: 4 923
Спасибо сказали: 239 раз




Код
if(preg_match('#не поддерживает пинга#',$linie[$i])){

Стоит добавить и англоязычный вариант, хотя в своем пингере это никак не отслеживаю, так как каждый хаб выдает сообщения такие какие ему заблагорассудится. У меня это выглядит как таймаут.

Код
$user = explode(' ', $linie[$i]);

$user - совершенно не информативное название переменной для данного случая, возможно стоит заменить на что-то более понятное. Но это больше относиться к стилю написания кода, чем к его работе.

Код
execute($socket, '$Supports NoGetINFO NoHello UserIP2 Feed MCTo HubTopic ClientID MiniSlots GetZBlock ADCGet CHUNK GetCID BotINFO');

Думаю стоит оставить лишь те характеристики, что действительно поддерживаются пингером. Например, GetZBlock и ADCGet служат для скачиваний файлов.

Код
execute($socket, '$Key '.lock2key($user[1],$data['Port']));

Порт следует убрать, так как функция принимает только один параметр, а не два.

Код
case '$Hello':
                    if ($user[1] == $nick) {

Если уж и делаеться проверка, то в случае ее не прохождения надо тоже что-то делать, не правда ли? Иначе зачем она нужна.

Код
execute($socket, '$MyINFO $ALL '.$nick.' Bot by dro <++ V:0.674,M:A,H:1/0/1,S:20>$ $LAN(T3).$alexandr@drozdin.ru$'.$myshare.'$');

На некоторые хабы пингер не зайдет с подстрокой "Bot" в описании пользователя, если там есть админы, которые борются с ботами и ставят фильтры.

Код
execute($socket, '$BotINFO {HubListPinger} hublist pinger');

Вы не проверили того, что хаб поддерживает данную команду, в ответных Supports. Я уже писал об этом.

Код
    $hubinfo[1] = str_replace("<", "<", $hubinfo[1]);
    $hubinfo[1] = str_replace(">", ">", $hubinfo[1]);
    $hubinfo[3] = str_replace("<", "<", $hubinfo[3]);
    $hubinfo[3] = str_replace(">", ">", $hubinfo[3]);

Или часть кода прошла преформатирование при выводе на форум или тут вы делаете что-то не то.

Код
$hubinfo = str_replace( "HubINFO ", "", $hubinfo);

У вас нет гарантий, что переменная $hubinfo будет инциализирована, после выполнения кода находящегося выше.

Код
$hubinfo[3] = str_replace(".px.", " ", $hubinfo[3]);

Некорректное решение в общем случае, так как заменяет везде ".px." на пробел. Хаб PtokaX дописывает данную строку лишь в самый конец, т. е. вам стоит проверять последние 4 символа на предмет соответствия и извлекать подстроку, если это так.

Код
        $hubinfo[1] = $hubname;

Опять же, инициализация переменной не гарантирована. Следите за этим. Ничего страшного в PHP не происходит, только warning'и, которые замедляют работу скрипта, вызывая обращения к логам, но если бы вы писали на C, то все может закончиться куда плачевнее. Помните, что когда вы пишете код, вы порождаете свой стиль, с которым потом будет трудно бороться, если вы смените язык программирования.

Код
array_unique($info);

Вы делаете ошибку вызывая эту функцию. Ознакомтесь с ее действием. Пример ошибки: У двух пользователей размер шары одинаковый до байта, например равне 0 - вы подсчитаете лишь одного из них.

Код
            $total_share=$share+$total_share;
        }
        $total_share=$total_share - $myshare;

Старайтесь, где это возможно, использовать операторы "+=" и "-=".

Код
        mysql_query("UPDATE `".$dbtable."` SET Name = '".$hubinfo[1]."',Descr = '".$hubinfo[3]."',
                     Maxusers = '".$hubinfo[4]."', MinShare = '".$hubinfo[5]."', MinSlots = '".$hubinfo[6]."',
                     MaxHubs = '".$hubinfo[7]."', Soft = '".$hubinfo[8]."'  WHERE id = ".$data['ID']."");

Типичный пример включения не проверенных данных в SQL запрос, может приводит к SQL иньекции, со всеми отсюда вытекающими последствиями. Необходимо все строковые значения пропускать через функцию mysql_real_escape_string, все целочисленные - через intval, а дробные через floatval. Это касается всех MySQL запросов.

Код
    mysql_query("UPDATE `".$dbtable."` SET Users = ".$useri.", Status = 'Online', Share = ".floatval($total_share)." WHERE id = ".$data['ID']."");

Чтобы не терять часть значащих знаков, я предпочитаю с $total_share работать, как со строкой. Преобразование к дробному числу может перевести к потери нескольких значащих знаков. Соответственно для MySQL таблицы нужно указать BIGINT поле для хранения таких чисел, ну или VARCHAR, хотя это и не очень хорошо.

Код
    if ($useri > $data['Userspeak']){

Замечание по стилю именования: "Userspeak" имеет две расшифровки, "user speak" и "users peak", для большей понятности кода такую двойственность лучше не создавать. Например, "usersPeak" или "users_peak".

Код
    mysql_query("UPDATE `".$dbtable."` SET Status = 'Offline' WHERE id = ".$data['ID']."");
    mysql_query("UPDATE `".$dbtable."` SET Users = '0' WHERE id = ".$data['ID']."");
    mysql_query("UPDATE `".$dbtable."` SET Share = '0' WHERE id = ".$data['ID']."");

В данном случае следует выполнять один запрос к БД, а не три. Также, если используется InnoDB в качества движка таблиц, то рекомендуется использовать явно задание транзакций, если число запросов на изменение, составляющих атомарную цепочку, более одного.


Спасибо сказали:
Go to the top of the page
+Quote Post
dro
сообщение 30.8.2010, 9:06
Сообщение #98


Начинающий
*

Группа: Пользователи
Сообщений: 13
Регистрация: 16.8.2010
Пользователь №: 7 500
Спасибо сказали: 0 раз




Спасибо большое, щас буду исправлять.

Насчет
Код
array_unique($info);


В $info содержиться не только шара но и ник юзера типа Вася - 123123123
и я не думаю что может быть на хабе 2 одинковых юзера.

Цитата
Или часть кода прошла преформатирование при выводе на форум или тут вы делаете что-то не то.


Форум преформатировал.

Не совсем понял про то, что если у нас не выполниться if ($user[1] == $nick) {

т.е. проверка не нужна?

Ладно пойду налью кофе и буду фиксить все.
По поводу SQL inj вы правы, лень матушка меня на такое подвела. Исправлюсь.
Go to the top of the page
+Quote Post
Enyby
сообщение 30.8.2010, 10:34
Сообщение #99


Освоившийся участник
*****

Группа: Пользователи
Сообщений: 391
Регистрация: 4.11.2009
Из: Дом
Пользователь №: 4 923
Спасибо сказали: 239 раз




Цитата
array_unique — Removes duplicate values from an array

values, в данном случае, это размер шары пользователей. Зачем вам оставлять только пользователей с уникальным размером шары? Это значение, если отлично от нуля, то вероятность его совпадения у разных пользователей очень мала, но если оно равно нулю, или один пользователь сидит два раза на одном хабе, то вы попросту отсеете его.
Вы и так уже заносите в массив по никнейму как ключу, а одному ключу может соответствовать лишь одно значение массива, так что эта команда совершенно лишняя.

Код
    $hubinfo[1] = str_replace("<", "<", $hubinfo[1]);
    $hubinfo[1] = str_replace(">", ">", $hubinfo[1]);
    $hubinfo[3] = str_replace("<", "<", $hubinfo[3]);
    $hubinfo[3] = str_replace(">", ">", $hubinfo[3]);

Даже если форматирование, такого рода замены можно ускорить, сделав их одновременно, еще до этапа разбивки на части $hubinfo:
Код
    $hubinfo = str_replace(array("<", ">", "HubINFO "), array("<", ">", ""), $hubinfo[1]);
    $hubinfo = explode('$', $hubinfo);
    $hubinfo[3] = str_replace(".px.", " ", $hubinfo[3]);


Код
                case '$Hello':
                    if ($user[1] == $nick) {
                    execute($socket, '$Version 1,0091');
                    execute($socket, '$GetNickList');
                    execute($socket, '$MyINFO $ALL '.$nick.' Bot by dro <++ V:0.674,M:A,H:1/0/1,S:20>$ $LAN(T3).$alexandr@drozdin.ru$'.$myshare.'$');
                    #execute($socket, '$MyINFO $ALL '.$nick.' Bot by dro <FlylinkDC++ V:(r386),M:P,H:1/0/1,S:15>$ $100    $alexandr@drozdin.ru$670969607454$');
                    execute($socket, '$BotINFO {HubListPinger} hublist pinger');
                    }
else {
// some code
}

Просто если ники не совпадут, то вы не отошлете кучу команд, грубо говоря, вы проигнорируете команду хаба и будете ждать у моря погоды. Необходимо делать обработчики всех возможных событий. Если вы делаете if, то он может как выполниться, так и не выполниться. Нужно учитывать оба варианта.


Спасибо сказали:
Go to the top of the page
+Quote Post
Enyby
сообщение 30.11.2010, 1:51
Сообщение #100


Освоившийся участник
*****

Группа: Пользователи
Сообщений: 391
Регистрация: 4.11.2009
Из: Дом
Пользователь №: 4 923
Спасибо сказали: 239 раз




Много релевантных слов. Конкретного хаблиста тут нет, так что добавлять некуда.
Go to the top of the page
+Quote Post

5 страниц V  « < 3 4 5
Ответить в данную темуНачать новую тему
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

Collapse

> Похожие темы

  Тема Ответов Автор Просмотров Последнее сообщение
No New Posts От: Хаблисты
От темы с ID: 5075
2 feardc 4 456 30.4.2016, 12:07 Посл. сообщение: feardc
No New Posts Topic has attachmentsХаблисты
Некоторое количество хаблистов
9 Enyby 11 792 17.12.2011, 2:46 Посл. сообщение: Enyby
No New Posts От: Хаблисты
От темы с ID: 404
0 absent 3 626 30.11.2010, 1:40 Посл. сообщение: absent
No New Posts От: Хаблисты
От темы с ID: 404
0 Accelerator 4 482 21.4.2010, 6:47 Посл. сообщение: Accelerator
No New Posts Хаблисты
1 KamoK 6 047 1.12.2009, 11:54 Посл. сообщение: Артём

 



RSS Сейчас: 27.11.2024, 3:59