Хаблисты |
Здравствуйте, гость ( Вход | Регистрация )
Хаблисты |
20.8.2010, 1:38
Сообщение
#81
|
|
Освоившийся участник Группа: Пользователи Сообщений: 391 Регистрация: 4.11.2009 Из: Дом Пользователь №: 4 923 Спасибо сказали: 239 раз |
Пингом - быстрей, но пинг предоставляет недостаточно информации. С другой стороны, он виден админу, и если часто пинговать, то вас попросту забанят. Поэтому у меня раз в 5 минут хаблист заходит как клиент и раз в час - как пингер, т. е. каждый 12 раз из тех, что по 5 минут.
В целом пингер неплох. Критика по коду:
Чтобы бота пускали на все хабы, не нужно передавать специфический тэг клиента. Да и число хабов онлайн можно не 21 ставить. "H:21/0/1" - 21 хаб 1 и на одном админ. UPD: И да, я тут увидел зачатки работы как клиента (Подсчет MyINFO). Вам предстоит нетривиальная задача определения когда заканчивается процесс инициализации хаба. Также вам необходимо отсевать свой собственный MyINFO, так как он вносит погрешность в ваши измерения. В дополнение к этому есть скрипты манипулирующие MyINFO, из-за них оно может приходить несколько раз для одного пользователя, что вызовет искажение размера шары и числа пользователей. Так что работы тут еще много. |
|
|
20.8.2010, 9:03
Сообщение
#82
|
|
AmxModx Scripter Группа: Пользователи Сообщений: 302 Регистрация: 2.12.2008 Из: Королев Пользователь №: 1 283 Спасибо сказали: 127 раз |
Можно считать, что процесс инициализации закончился, если команды MyINFO уже были, и пришла первая не MyINFO команда
|
|
|
20.8.2010, 12:13
Сообщение
#83
|
|
Начинающий Группа: Пользователи Сообщений: 13 Регистрация: 16.8.2010 Пользователь №: 7 500 Спасибо сказали: 0 раз |
2Enyby Спасибо за критику и советы. Lock поправил
По поводу MyINFO можно поидеи себя отсеять сделав -1 (+- 2 чел не сыграют роли) Так же можно сделать и с шарой. Но вот Вы правильно заметили что может придти несколько раз MyINFO, на этот счет я думаю загонять все данные в массив и потом массив проверять на одинакове эл-ты, а далее уже из этого массива и будем считать шару и число юзеров за вычетом моих данных. Верно ли это? Бывает такое что хаб после MyINFO рвет соединение и скрипт отработал впустую, например dc.cifracom.ru Собственно по какому принципу лучше смотреть когда заканчивается процесс инициализации хаба? |
|
|
20.8.2010, 13:00
Сообщение
#84
|
|
Освоившийся участник Группа: Пользователи Сообщений: 391 Регистрация: 4.11.2009 Из: Дом Пользователь №: 4 923 Спасибо сказали: 239 раз |
Итак, по порядку.
Как было справделиво замеченно, можно отсекать по команде не MyINFO, после MyINFO, но не все тут гладко. Можно довольно долго висеть на хабе из 5 человек ожидая другой команды. Вообще говоря, по протоколу, список MyINFO, должен заканчиваться MyINFO хаблиста, но, к сожалению, так поступают не все хабы. Дальше. Есть такое расширение протокола как Zon. Которое предполагает сжатие gzip дл передаваемых данных. проблема состоит в том, что некоторые хабы в любом случае включат это сжатие не смотря поддерживается оно клиентом или нет. Эта команда может появляться где угодно и, обычно, список пользователей передается в сжатом виде, что означает, что ее нужно игнорировать и не разрывать соединение, так как процесс входа на хаб может быть не завершен. Также следует отслеживать команды ValidateDenide и ForceMove. Первая означает что ник занят или не является допустимым, а вторая - дает редирект, при переполнении или других причинах. Четкой команды, свидетельствующей о бане не существует, обычно это сообщение от бота со словом ban, но не обязательно. 100% алгоритма определения окончания инициализации не существует или мне он не известен. Пользуюсь набором правил следующего вида:
Как вариант, можно еще пытаться отлавливать MOTD, но оно может отсылаться в ЛС. По поводу дубликатов, проблема решается просто, все это дело заноситься в ассциативный массив по ключу ника, а потом из массива и считается шара и число пользователей. Также необходимо отслеживать свой ник и его игнорировать. Еще. Хаб может не поддерживать BotINFO/HubINFO, тогда с текущим алгоритмом вы будете ждать вечность команды HubINFO. Чтобы этого не произошло, необходимо, после указания поддержки данных команд в отсылаемом Supports, проверить наличие поддержи в полученном Supports. |
|
|
20.8.2010, 13:38
Сообщение
#85
|
|
Начинающий Группа: Пользователи Сообщений: 13 Регистрация: 16.8.2010 Пользователь №: 7 500 Спасибо сказали: 0 раз |
С шарой и ассоциативным массивом я так и сделал.
А насчет остального буду думать и дописывать спасибо!!!!! |
|
|
20.8.2010, 15:44
Сообщение
#86
|
|
7 квадратиков Группа: Модераторы Сообщений: 793 Регистрация: 21.1.2009 Пользователь №: 1 895 Спасибо сказали: 301 раз |
[*]Если получена команда 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$$ |
|
|
20.8.2010, 15:58
Сообщение
#87
|
|
Освоившийся участник Группа: Пользователи Сообщений: 391 Регистрация: 4.11.2009 Из: Дом Пользователь №: 4 923 Спасибо сказали: 239 раз |
Спасибо за замечание. Мне оно правда не грозит, так как хаблист локальный, но буду знать.
Вообще говоря, самописные хабы это страшная сила, наподобие IE 6 при верстке. У меня были проблемы с dcworlds, но он уже не локальный, да и давно уже это было, не помню сути. Помню только что нарушался протокол и хаб был самописным. |
|
|
29.8.2010, 15:25
Сообщение
#88
|
|
Начинающий Группа: Пользователи Сообщений: 13 Регистрация: 16.8.2010 Пользователь №: 7 500 Спасибо сказали: 0 раз |
А подскажите такой момент.
У меня кол-во пользователей с действительным расходится примерно на 100. Где искать косяк? Или это из-за того что не все клиенты сразу отвечают на MyInfo? И как быть тогда? |
|
|
29.8.2010, 16:08
Сообщение
#89
|
|
Освоившийся участник Группа: Пользователи Сообщений: 391 Регистрация: 4.11.2009 Из: Дом Пользователь №: 4 923 Спасибо сказали: 239 раз |
1. Включаешь вывод всех входящих/отправленных команд и получаешь лог файл.
2. В отладчике ДС клиента заходишь на тот же хаб - получаешь второй лог. 3. Ищешь отличия. Чтобы не делать это руками, организуй вывод со своего хаблиста в формат аналогичный отладчику, а потом пользуйся утилитами сравнения файлов, например, тем же тоталом коммандером. 4. Если отличия есть, то причина в том что ты рано закрыл соединение. 5. Если нет, то причина в обработке внутри пингера - начинаешь во всю использовать print_r и var_dump. UPD: И да, на майинфо отвечает не клиент а хаб. И отсылает он сразу все, вот только иногда он это криво делает. |
|
|
29.8.2010, 17:23
Сообщение
#90
|
|
AmxModx Scripter Группа: Пользователи Сообщений: 302 Регистрация: 2.12.2008 Из: Королев Пользователь №: 1 283 Спасибо сказали: 127 раз |
Причина может быть в том, что у тебя в цикле читаются данные из сокета, потом эти данные разбиваются по |.
Когда данных пришло меньше, чем 2048, все хорошо. Но когда хаб большой, все MyINFO за одно чтение получить не удается, и выходит, что из сокета прочиталось часть MyINFO, то есть конец буфера выглядит так: "... |$MyINF". И остальная часть MyINFO прочитается только при следующем чтении. Но увеличиваться счетчик юзеров не будет, так как первая часть MyINFO не распознается как MyINFO. |
|
|
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: На самом деле не важно где прервалсь команда, на ключевом слове или где-то еще, в любом случае дальнейшая обработка фрагмента будет ошибочной. |
|
|
29.8.2010, 19:01
Сообщение
#92
|
|
Главный ра******й тут... Группа: Главные администраторы Сообщений: 1 727 Регистрация: 18.5.2008 Из: RF, 2la Пользователь №: 1 Спасибо сказали: 776 раз |
Да, но прибавлять последний элемент массива надо лишь при условии что он не заканчивается |, иначе получится дубляж некоторых команд, что конечно может и не быть критичным, но все-таки неверно. Хотя как я тут вижу, если команды были полными, то приплюсуется лишь пустая строка
|
|
|
29.8.2010, 19:05
Сообщение
#93
|
|
Освоившийся участник Группа: Пользователи Сообщений: 391 Регистрация: 4.11.2009 Из: Дом Пользователь №: 4 923 Спасибо сказали: 239 раз |
Последний элемент не может заканчиваться символом "|", так как функция explode разбивает по нему на элементы массива. Если же "|" будет последним символом в строке, то в массиве последний элемент будет пустой строкой.
|
|
|
29.8.2010, 21:02
Сообщение
#94
|
|
Начинающий Группа: Пользователи Сообщений: 13 Регистрация: 16.8.2010 Пользователь №: 7 500 Спасибо сказали: 0 раз |
Частично понял о чем речь!
Спасибо буду дальше разбираться З.Ы. А если размер буффера поставить больше? UPD: Вроде бы все стало считать отдично!!! Благодарю Вас! |
|
|
29.8.2010, 22:04
Сообщение
#95
|
|
Освоившийся участник Группа: Пользователи Сообщений: 391 Регистрация: 4.11.2009 Из: Дом Пользователь №: 4 923 Спасибо сказали: 239 раз |
А если размер буффера поставить больше? Возврат из функции socket_read происходит по двум причинам:
Если буфер слишком мал, то скрипт будет частенько бегать в цикле, не обрабатывая команды, а лишь инкрементно приращая переменную $end. Если же буфер слишком велик, то большую часть времени скрипт будет ждать таймаута заполнения буфера, в результате чего, хаб имеет право разорвать соединение, как слишком медленное, но даже если этого не произойдет, все равно будет существенное падение скорости работы пингера. |
|
|
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
Причина редактирования: Такой большой код лучше прятать под спойлер!
|
|
|
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 в качества движка таблиц, то рекомендуется использовать явно задание транзакций, если число запросов на изменение, составляющих атомарную цепочку, более одного. |
|
|
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 вы правы, лень матушка меня на такое подвела. Исправлюсь. |
|
|
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, то он может как выполниться, так и не выполниться. Нужно учитывать оба варианта. |
|
|
30.11.2010, 1:51
Сообщение
#100
|
|
Освоившийся участник Группа: Пользователи Сообщений: 391 Регистрация: 4.11.2009 Из: Дом Пользователь №: 4 923 Спасибо сказали: 239 раз |
Много релевантных слов. Конкретного хаблиста тут нет, так что добавлять некуда.
|
|
|
Похожие темы
Тема | Ответов | Автор | Просмотров | Последнее сообщение | |
---|---|---|---|---|---|
От: Хаблисты От темы с ID: 5075 |
2 | feardc | 4 456 | 30.4.2016, 12:07 Посл. сообщение: feardc | |
Хаблисты Некоторое количество хаблистов |
9 | Enyby | 11 792 | 17.12.2011, 2:46 Посл. сообщение: Enyby | |
От: Хаблисты От темы с ID: 404 |
0 | absent | 3 626 | 30.11.2010, 1:40 Посл. сообщение: absent | |
От: Хаблисты От темы с ID: 404 |
0 | Accelerator | 4 482 | 21.4.2010, 6:47 Посл. сообщение: Accelerator | |
Хаблисты | 1 | KamoK | 6 047 | 1.12.2009, 11:54 Посл. сообщение: Артём |
|
Сейчас: 27.11.2024, 2:59 |