<?xml version="1.0" encoding="utf-8" ?> 
<rss version="2.0">
<channel>
<title>Сообщество: Программисты</title> 
<link>http://scrolls.combats.com/~developers/</link> 
<description>Программисты - scrolls.combats.com</description> 
<lastBuildDate>Tue, 23 Jun 2009 00:54:00 GMT</lastBuildDate> 
<generator>scrolls.combats.com - Скроллы Бойцовского Клуба</generator> 
<image>
<url>http://scrolls.combats.com/i/avatar/big/u300.jpg</url> 
<title>developers</title> <link>http://scrolls.combats.com/~developers/</link><width>90</width> 
<height>80</height> 
</image>
<item>
<guid isPermaLink="true">http://scrolls.combats.com/community/~developers/522691.html</guid> 
<pubDate>Tue, 23 Jun 2009 00:54:00 GMT</pubDate> 
<link>http://scrolls.combats.com/community/~developers/522691.html</link><author>developers : чесло зверя</author>
<title>Клановые абилки</title>
<description>Всем привет.&lt;br&gt;В Бк я играю не так давно так что если гдето буду неправ поправте..&lt;br&gt;Из разговоров с бывалыми игроками я узнал что давным давно за высокое место клана в рейтинге давались игровые бонусы, но по какимто непонятным причинам админы это отменили. Изза этого из Бк произошел большой отток людей делавших игру интересней (журналистов, прогеров, писателей и тд) т.к. стало бессмыслено тратить личное время на то чтобы сделать сайт своего клана более интересным и полезным. Сечас мы имеем такую ситуацию, что более-менее поддерживаются от силы 10 клановых сайтов, а на все остальные уже давно забили. Новых прогамных ресурсов не появляется вобще, а те которые есть уже практически не развиваются, в лучшем случае только поддерживаются &lt;br&gt;&lt;br&gt;Думаю такое положение дел плохо для всех сторон:&lt;br&gt; - для творческих людей, которые по натуре азартны и хотелибы проявить свое мастерство и посостязаться со своими коллегами, кто сможет сделать свой сайт самым лучшим, но при текущем положении дел это будет борьба ради борьбы, т.к. награды нет никакой&lt;br&gt; - для игроков. Во первых по изложеным выше причинам игра не так интересна как могла бы быть. Во вторых если админы внесут какието существеные изменения в игру, то не факт что имеющиеся ресурсы (переодевалки, карты и тд) к ним адаптируют за короткие сроки, если адаптируют вобще (опятьже трудится над этим большого резона нет).&lt;br&gt; - для админов. Тут в принципе все то же самое что и для игроков только с админской колокольни, то есть 1) играет не так много народу как могло бы 2) они самим по какимто причинам немогут писать подробную помощь по нововедениям и предаставлять хотябы самые необходимые ресурсы (карты, переодевалку и тд), по этому этим занимаются кланы, но делают это на энтузиазме и поэтому вобщем коекак&lt;br&gt;&lt;br&gt;К чему я все это написал.. Хотел узнать мнение прогерской обществености по этому поводу и если эта проблема небезразлична нетолько мне вместе написать обращение к админам с просьбой вернуть поощерение за место в рейтинге.. И попросить дать четкий ответ будет это сделано или нет.. Если под обращением подпишутся уважаемые людей с высоким уровнем врядли они его проигнорируют.</description> 
</item>
<item>
<guid isPermaLink="true">http://scrolls.combats.com/community/~developers/499006.html</guid> 
<pubDate>Wed, 27 May 2009 04:56:00 GMT</pubDate> 
<link>http://scrolls.combats.com/community/~developers/499006.html</link><author>developers : Vikis</author>
<title>Получение инфы о персонаже</title>
<description>Доброй ночи. &lt;br&gt;Имеется код  для выдирания инфы о персонаже из БК. Код работоспособен только на 25-30 записей  в БД. Далее айпи блокируется и соответственно выдаётся ошибка:). Я приводил этот код в комментариях тремя постами ниже, мне посоветовали выставить sleep (3); &lt;br&gt;Выставил, но нифига не прошло. Обновились 34 записи а дальше как всегда :&quot;Ваш IP временно заблокирован...&lt;br&gt;&lt;br&gt;Собственно сам код &lt;div id=&quot;s_17246753_2&quot; style=&quot;display:&quot;&gt;&lt;a href=&quot;#&quot; onClick=&quot;document.all.s_17246753_2.style.display=&#39;none&#39;; document.all.s_17246753_1.style.display=&#39;&#39;;return false;&quot;&gt;[&#37;param.l.filters.Show&#37;]&lt;/a&gt;&lt;/div&gt;&lt;div id=&quot;s_17246753_1&quot; style=&quot;display:none&quot;&gt;&lt;a href=&quot;#&quot; onClick=&quot;document.all.s_17246753_1.style.display=&#39;none&#39;; document.all.s_17246753_2.style.display=&#39;&#39;;return false;&quot;&gt;[&#37;param.l.filters.Hide&#37;]&lt;/a&gt;&lt;br/&gt;&lt;?&lt;br&gt;include_once(&quot;mysql.php&quot;);&lt;br&gt;&lt;br&gt;class CURL {&lt;br&gt;   var $callback = false;&lt;br&gt;&lt;br&gt;function setCallback($func_name) {&lt;br&gt;   $this-&gt;callback = $func_name;&lt;br&gt;}&lt;br&gt;&lt;br&gt;function doRequest($method, $url, $vars) {&lt;br&gt;   $ch = curl_init();&lt;br&gt;curl_setopt($ch, CURLOPT_URL, $url);&lt;br&gt;curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);&lt;br&gt;curl_setopt($ch, CURLOPT_HEADER, 0);&lt;br&gt;curl_setopt($ch, CURLOPT_TIMEOUT, 7);&lt;br&gt;curl_setopt($ch, CURLOPT_MAXREDIRS, 3);&lt;br&gt;curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);&lt;br&gt;curl_setopt($ch, CURLOPT_FAILONERROR, true);&lt;br&gt;curl_setopt($ch, CURLOPT_ENCODING, &#39;gzip&#39;);&lt;br&gt;   //curl_setopt($ch, CURLOPT_URL, $url);&lt;br&gt;   //curl_setopt($ch, CURLOPT_HEADER, 0);&lt;br&gt;   //curl_setopt($ch, CURLOPT_TIMEOUT, 1);&lt;br&gt;   //curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER[&#39;HTTP_USER_AGENT&#39;]);&lt;br&gt;   //curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);&lt;br&gt;   //curl_setopt($fh, CURLOPT_REFERER, &#39;http://knl/&#39;);&lt;br&gt;   //curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);&lt;br&gt;   //curl_setopt($ch, CURLOPT_COOKIEJAR, &#39;cookie.txt&#39;);&lt;br&gt;   //curl_setopt($ch, CURLOPT_COOKIEFILE, &#39;cookie.txt&#39;);&lt;br&gt;   if ($method == &#39;POST&#39;) {&lt;br&gt;       curl_setopt($ch, CURLOPT_POST, 1);&lt;br&gt;       curl_setopt($ch, CURLOPT_POSTFIELDS, $vars);&lt;br&gt;   }&lt;br&gt;   $data = curl_exec($ch);&lt;br&gt;   curl_close($ch);&lt;br&gt;   if ($data) {&lt;br&gt;       if ($this-&gt;callback)&lt;br&gt;       {&lt;br&gt;           $callback = $this-&gt;callback;&lt;br&gt;           $this-&gt;callback = false;&lt;br&gt;           return call_user_func($callback, $data);&lt;br&gt;       } else {&lt;br&gt;           return $data;&lt;br&gt;       }&lt;br&gt;   } else {&lt;br&gt;       return curl_error($ch);&lt;br&gt;   }&lt;br&gt;}&lt;br&gt;&lt;br&gt;function get($url) {&lt;br&gt;   return $this-&gt;doRequest(&#39;GET&#39;, $url, &#39;NULL&#39;);&lt;br&gt;}&lt;br&gt;&lt;br&gt;function post($url, $vars) {&lt;br&gt;   return $this-&gt;doRequest(&#39;POST&#39;, $url, $vars);&lt;br&gt;}&lt;br&gt;}&lt;br&gt;&lt;br&gt;&lt;br&gt;if (&#33;function_exists(&#39;array_combine&#39;)) {&lt;br&gt;   function array_combine($a, $b) {&lt;br&gt;       $c = array();&lt;br&gt;       if (is_array($a) &amp;&amp; is_array($b))&lt;br&gt;           while (list(, $va) = each($a))&lt;br&gt;               if (list(, $vb) = each($b))&lt;br&gt;                   $c[$va] = $vb;&lt;br&gt;               else&lt;br&gt;                   break 1;&lt;br&gt;       return $c;&lt;br&gt;   }&lt;br&gt;}&lt;br&gt;&lt;br&gt;   function doPost($uri,$postdata,$host){&lt;br&gt;       $da = fsockopen($host, 80, $errno, $errstr);&lt;br&gt;       if (!$da) {&lt;br&gt;           echo &quot;$errstr ($errno)&lt;br/&gt;\n&quot;;&lt;br&gt;           echo $da;&lt;br&gt;       }&lt;br&gt;       else {&lt;br&gt;           $salida =&quot;POST $uri  HTTP/1.1\r\n&quot;;&lt;br&gt;           $salida.=&quot;Host: $host\r\n&quot;;&lt;br&gt;           $salida.=&quot;User-Agent: PHP Script\r\n&quot;;&lt;br&gt;           $salida.=&quot;Content-Type: application/x-www-form-urlencoded\r\n&quot;;&lt;br&gt;           $salida.=&quot;Content-Length: &quot;.strlen($postdata).&quot;\r\n&quot;;&lt;br&gt;           $salida.=&quot;Connection: close\r\n\r\n&quot;;&lt;br&gt;           $salida.=$postdata;&lt;br&gt;           fwrite($da, $salida);&lt;br&gt;                     while (!feof($da))&lt;br&gt;               $response.=fgets($da, 128);&lt;br&gt;           $response=split(&quot;\r\n\r\n&quot;,$response);&lt;br&gt;           $header=$response[0];&lt;br&gt;           $responsecontent=$response[1];&lt;br&gt;           if(!(strpos($header,&quot;Transfer-Encoding: chunked&quot;)===false)){&lt;br&gt;               $aux=split(&quot;\r\n&quot;,$responsecontent);&lt;br&gt;               for($i=0;$i&lt;count($aux);$i++)&lt;br&gt;                   if($i==0 || ($i&#37;2==0))&lt;br&gt;                       $aux[$i]=&quot;&quot;;&lt;br&gt;               $responsecontent=implode(&quot;&quot;,$aux);&lt;br&gt;           }//if&lt;br&gt;           return chop($responsecontent);&lt;br&gt;       }//else&lt;br&gt;   }//function-doPost&lt;br&gt;&lt;br&gt;$ar_complete=array();&lt;br&gt;$ar_keys=array();&lt;br&gt;$ar_items=array();&lt;br&gt;&lt;br&gt;function myarray(&amp;$item)&lt;br&gt;{&lt;br&gt;global $ar_keys;&lt;br&gt;global $ar_items;&lt;br&gt;&lt;br&gt;$tmp_ar=split(&quot;=&quot;,$item);&lt;br&gt;$ar_keys[]=$tmp_ar[0];&lt;br&gt;$ar_items[]=$tmp_ar[1];&lt;br&gt;}&lt;br&gt;&lt;br&gt;function print_rf($str)&lt;br&gt;{&lt;br&gt;echo(&quot;&lt;pre&gt;&quot;);&lt;br&gt;print_r($str);&lt;br&gt;echo(&quot;&lt;/pre&gt;&quot;);&lt;br&gt;}&lt;br&gt;&lt;br&gt;$result = mysql_query (&quot;SELECT login,gamecity_url FROM &quot;.ST_TABLE, $LINK) or die(&quot;index.php -&gt; err &quot;.mysql_error($LINK));&lt;br&gt;&lt;br&gt;if ($row-&gt;gamecity==&quot;&quot;)&lt;br&gt;{&lt;br&gt;$gamecity=&quot;http://emeraldscity.combats.com&quot;;&lt;br&gt;} else {&lt;br&gt;$gamecity=$row-&gt;gamecity_url;&lt;br&gt;}&lt;br&gt;&lt;br&gt;$curl=new CURL;&lt;br&gt;&lt;br&gt;for ($i = 0; $i &lt; mysql_num_rows ($result); $i++) {&lt;br&gt;  $row = mysql_fetch_object ($result);&lt;br&gt;//$url=$gamecity.&quot;/inf.pl?login=&quot;.$row-&gt;login.&quot;&amp;short=1&quot;;&lt;br&gt;//$p_url=parse_url($gamecity);&lt;br&gt;&lt;br&gt;$contents=$curl-&gt;post($gamecity.&quot;/inf.pl&quot;,&quot;login=&quot;.$row-&gt;login.&quot;&amp;short=1&quot;);&lt;br&gt;&lt;br&gt;//$contents = @doPost(&quot;/inf.pl&quot;,&quot;login=&quot;.$row-&gt;login.&quot;&amp;short=1&quot;,$p_url[host]);&lt;br&gt;if (stristr($contents,&quot;[503]&quot;)) break;&lt;br&gt;if (stristr($contents,&quot;The document has moved&quot;)) {&lt;br&gt;    sleep(3);&lt;br&gt;  $host=stristr($contents,&quot;http://&quot;);&lt;br&gt;  $host=str_replace(&quot;\n&quot;,&quot;&quot;,$host);&lt;br&gt;  $host=str_replace(&quot;\r&quot;,&quot;&quot;,$host);&lt;br&gt;  $host=str_replace(&quot; &quot;,&quot;&quot;,$host);&lt;br&gt;  $pos = strpos($host, &#39;&quot;&#39;, 1);&lt;br&gt;  $url=substr($host, 0, $pos);&lt;br&gt;  $p_url=parse_url($url);&lt;br&gt;  $contents =$curl-&gt;post(&quot;http://&quot;.$p_url[host].&quot;/inf.pl&quot;,&quot;login=&quot;.$row-&gt;login.&quot;&amp;short=1&quot;);&lt;br&gt;  //$contents = @doPost(&quot;/inf.pl&quot;,&quot;login=&quot;.$row-&gt;login.&quot;&amp;short=1&quot;,$p_url[host]);&lt;br&gt;}&lt;br&gt;&lt;br&gt;$ar=$ar_complete=$ar_keys=$ar_items=array();&lt;br&gt;$ar=split(&quot;\n&quot;,$contents);&lt;br&gt;array_walk($ar,&#39;myarray&#39;);&lt;br&gt;$ar_complete = array_combine ( $ar_keys, $ar_items );&lt;br&gt;&lt;br&gt;$login=$row-&gt;login;&lt;br&gt;if (!array_key_exists(&quot;login_online&quot;, $ar_complete)) {&lt;br&gt;  mysql_query (&quot;UPDATE `&quot;.ST_TABLE.&quot;` SET login_online=&#39;0&#39; WHERE login=&#39;$login&#39;&quot;) or die(&quot;update.php -&gt; err &quot;.mysql_error($LINK).&quot;\n&quot;);&lt;br&gt;  mysql_query (&quot;UPDATE `&quot;.ST_TABLE.&quot;` SET room_name=&#39;&#39; WHERE login=&#39;$login&#39;&quot;) or die(&quot;update.php -&gt; err &quot;.mysql_error($LINK)).&quot;\n&quot;;&lt;br&gt;}&lt;br&gt;foreach ($ar_complete as $key =&gt; $value) {&lt;br&gt;//print_rf($ar_complete);&lt;br&gt;//echo(&quot;UPDATE &quot;.ST_TABLE.&quot; SET &quot;.$key.&quot;=&#39;&quot;.$value.&quot;&#39; WHERE login=&#39;$login&#39;&quot;);&lt;br&gt;//exit;&lt;br&gt;&lt;br&gt;if (($row-&gt;key)!=$value) {&lt;br&gt;  //print_rf($row-&gt;$key);&lt;br&gt;//  print_rf($value);&lt;br&gt;&lt;br&gt;   //print_rf (&quot;UPDATE `&quot;.ST_TABLE.&quot;` SET &quot;$key&quot;=&#39;&quot;$value&quot;&#39; WHERE login=&#39;&quot;.$login.&quot;&#39;\n&quot;);&lt;br&gt;    mysql_query (&quot;UPDATE &quot;.ST_TABLE.&quot; SET &quot;.$key.&quot;=&#39;&quot;.$value.&quot;&#39; WHERE login=&#39;&quot;.$login.&quot;&#39;&quot;) or die(&quot;update.php -&gt; err &quot;.mysql_error($LINK).&quot;\n&quot;);&lt;br&gt;//exit;&lt;br&gt;  }&lt;br&gt;}&lt;br&gt;//set_time_limit(0);&lt;br&gt;sleep (3);&lt;br&gt;}&lt;br&gt;&lt;br&gt;mysql_free_result ($result);&lt;br&gt;?&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;Хотелось бы услышать ваше мнение.&lt;br&gt;</description> 
</item>
<item>
<guid isPermaLink="true">http://scrolls.combats.com/community/~developers/486699.html</guid> 
<pubDate>Tue, 12 May 2009 17:38:00 GMT</pubDate> 
<link>http://scrolls.combats.com/community/~developers/486699.html</link><author>developers : Alex Nomad</author>
<title>Хранение данных без cookies</title>
<description>Многие сталкиваюся в своем веб-программинге с необходимостью хранить пользовательские данные в cookies. Но ограничение в 3 Кб на домен портит весь кайф от работы с ними. Да и каждый запрос гонять их между клиентом и сервером тоже напрягает.&lt;br&gt;&lt;br&gt;Представляю вам подборку методов о том, как можно хранить пользовательские данные на компьютере клиентов, не вовлекая в это cookies.&lt;br&gt;&lt;br&gt;&lt;a href=&quot;http://forum.antichat.ru/showthread.php?p=714022&quot; target=&quot;_blank&quot;&gt;Хранение данных без cookies&lt;/a&gt; (Евгений Минаев)&lt;br&gt;&lt;br&gt;На всякий случай копирую в скролл  полный текст статьи.&lt;br&gt;&lt;br&gt;[color=#06088B]----[ NITRO ... ]&lt;br&gt;&lt;br&gt;&quot;Стою на шестом этаже пятиэтажного дома, да это незаконно, но здесь многим так знакомо&quot;&lt;br&gt;&lt;br&gt;Cookies впервые появились в Netscape, чтобы не хранить данные на веб сервере. Технология прижилась и даже с ростом вместимости жестких дисков до сих пор широко применяется. С появлением ajaxа и вследствие многократного увеличения запросов, приходится каждый раз при посылке запроса посылать также и cookies, что ведет к росту трафика, да и ограничение на них всего три килобайта. Первым эту проблему попытались исправить в Microsoft, внедрив поддержку userData в свой браузер пятой версии, но только после публикации предварительного описания HTML5 технология стала освещаться в различных веб изданиях. В статье расскажется об использовании данных в браузере на примерах Internet Explorer и Mozilla Firefox.&lt;br&gt;&lt;br&gt;----[ WHAT THE FUCK ?&#33; ... ] &lt;br&gt;&lt;br&gt;Из преимуществ можно отметить такие факты, как : уменьшение трафика, неограниченная длина данных, да и просто гарантия что у вас будет не как у всех xD. Применений такому способу масса - сохранение черновиков в веб формах, автозаполненных данных, хранение неособо важных данных, как дата последнего посещения, поисковый запрос или, например, название темы оформления сайта. Из достоинств метода можно выделить еще и безопасность - злоумышленник будет весьма удивлен отсутствию кук на сниффере. Но это вопрос времени. &lt;br&gt;&lt;br&gt;Так почему бы и не воспользоваться таким мощным и удобным средством?&lt;br&gt;&lt;br&gt;&lt;br&gt;----[ USER DATA ... ]&lt;br&gt;&lt;br&gt;userData появился в пятой версии Microsoft Internet Explorer и использовался для запоминания расположения элементов. Все данные представлены в виде связанной xml структуры в файле с расположением в Application Data/Microsoft/Internet Explorer/UserData. Первым технологию заметили программисты из Google. Чуть позже userData стали использовать как механизм хранения данных между сессиями. Все хранимые методы и свойства становятся доступными после события window.onload.&lt;br&gt;&lt;br&gt;Для начала работы с userData следует прописать определенную конструкцию в стиль документа.&lt;br&gt;&lt;br&gt;ie\:userdata {behavior:url(#default#userData);}&lt;br&gt;&lt;br&gt;После этого можно приступать к работе с данными, используя методы объекта.&lt;br&gt;&lt;br&gt;| Свойства &lt;br&gt;|&lt;br&gt;| expires&lt;br&gt;| Устанавливает или возвращает дату устаревания информации в хранилище&lt;br&gt;|&lt;br&gt;| XMLDocument&lt;br&gt;| Возвращает ссылку на объект XMLDocument, предоставляемый объектом&lt;br&gt;|&lt;br&gt;| Методы&lt;br&gt;|&lt;br&gt;| load (&lt;br&gt;| параметр object userDat Элемент, которому назначено поведение userData&lt;br&gt;| параметр string sStoreName Имя хранилища данных&lt;br&gt;| результат nothing )&lt;br&gt;|&lt;br&gt;| Метод load осуществляет чтение информации из хранилища данных.&lt;br&gt;| Для правильного выполнения метода load, элемент должен содержать установленный атрибут ID. &lt;br&gt;| &lt;html xmlns:IE&gt;&lt;br&gt;| &lt;head&gt;&lt;br&gt;| &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=windows-1251&quot;&gt;&lt;br&gt;| &lt;style type=&#39;text/css&#39;&gt;&lt;br&gt;| ie\:userdata {behavior:url(#default#userData);}&lt;br&gt;| &lt;/style&gt;&lt;br&gt;| &lt;/head&gt;&lt;br&gt;|&lt;br&gt;| &lt;body onload=&#39;oUserData.load(&quot;sDataStor&quot;);&#39;&gt;&lt;br&gt;| &lt;ie:userData ID=&quot;oUserData&quot; /&gt;&lt;br&gt;| &lt;/body&gt;&lt;br&gt;| &lt;/html&gt;&lt;br&gt;|&lt;br&gt;| save (&lt;br&gt;| параметр object userDat Элемент, которому назначено поведение userData&lt;br&gt;| параметр string sStoreName Имя хранилища данных&lt;br&gt;| результат nothing )&lt;br&gt;|&lt;br&gt;| Метод save осуществляет запись информации в хранилище данных. Доступность хранилища зависит от адреса ресурса, использующего &lt;br&gt;| это хранилище. Для того, что бы ресурс мог обратится к хранилищу данных, адрес ресурса, загружающего информацию из указанного &lt;br&gt;| хранилища данных, должен совпадать с адресом ресурса, создавшего это хранилище с точностью до всех используемых папок. &lt;br&gt;| &lt;html xmlns:IE&gt;&lt;br&gt;| &lt;head&gt;&lt;br&gt;| &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=windows-1251&quot;&gt;&lt;br&gt;| &lt;style type=&#39;text/css&#39;&gt;&lt;br&gt;| ie\:userdata {behavior:url(#default#userData);}&lt;br&gt;| &lt;/style&gt;&lt;br&gt;| &lt;/head&gt;&lt;br&gt;|&lt;br&gt;| &lt;body onunload=&#39;oUserData.save(&quot;sDataStor&quot;);&#39;&gt;&lt;br&gt;| &lt;ie:userData ID=&quot;oUserData&quot; /&gt;&lt;br&gt;| &lt;/body&gt;&lt;br&gt;| &lt;/html&gt;&lt;br&gt;|&lt;br&gt;| setAttribute (&lt;br&gt;| параметр string sAttrName Имя ключа&lt;br&gt;| параметр string vAttrValue Назначаемое ключу значение&lt;br&gt;| результат nothing )&lt;br&gt;| &lt;br&gt;| Метод setAttribute устанавливает значение нужному ключу, и в случае его отсутсвия сама добавляет ключ.&lt;br&gt;|&lt;br&gt;| getAttribute (&lt;br&gt;| параметр string sAttrName Имя ключа&lt;br&gt;| результат nothing )&lt;br&gt;|&lt;br&gt;| Метод getAttribute возвращает значение ключа или пустую строку.&lt;br&gt;|&lt;br&gt;| removeAttribute (&lt;br&gt;| параметр string sAttrName Имя ключа&lt;br&gt;| результат nothing )&lt;br&gt;|&lt;br&gt;| Метод getAttribute возвращает значение ключа или пустую строку.&lt;br&gt;|&lt;br&gt;|&lt;br&gt;| &lt;HEAD&gt;&lt;br&gt;|&lt;br&gt;| &lt;STYLE&gt;&lt;br&gt;| .userData {behavior:url(#default#userdata);}&lt;br&gt;| &lt;/STYLE&gt; &lt;br&gt;|&lt;br&gt;| &lt;SCRIPT&gt;&lt;br&gt;| function fnGet(){&lt;br&gt;| oPersistInput.load(&quot;oDataStore&quot;);&lt;br&gt;| oPersistInput.value=oPersistInput.getAttribute(&quot;sPersistAttr&quot;);&lt;br&gt;| }&lt;br&gt;| function fnSet(){&lt;br&gt;| oPersistInput.setAttribute(&quot;sPersistAttr&quot;,oPersistInput.value);&lt;br&gt;| oPersistInput.save(&quot;oDataStore&quot;);&lt;br&gt;| }&lt;br&gt;| function fnRem(){&lt;br&gt;| oPersistInput.removeAttribute(&quot;sPersistAttr&quot;);&lt;br&gt;| oPersistInput.save(&quot;oDataStore&quot;);&lt;br&gt;| }&lt;br&gt;| &lt;/SCRIPT&gt;&lt;br&gt;| &lt;/HEAD&gt;&lt;br&gt;|&lt;br&gt;| &lt;BODY&gt;&lt;br&gt;| &lt;INPUT type=text class=userData id=oPersistInput&gt; &lt;br&gt;| &lt;INPUT type=button value=&quot;Get Attribute&quot; onclick=&quot;fnGet()&quot;&gt;&lt;br&gt;| &lt;INPUT type=button value=&quot;Set Attribute&quot; onclick=&quot;fnSet()&quot;&gt;&lt;br&gt;| &lt;INPUT type=button value=&quot;Remove Attribute&quot; onclick=&quot;fnRem()&quot;&gt;&lt;br&gt;| &lt;/BODY&gt;&lt;br&gt;|&lt;br&gt;&lt;br&gt;----[ WINDOW.NAME ... ]&lt;br&gt;&lt;br&gt;DOM свойство я решил затронуть не просто так. Первым этот метод хранения данных предложил использовать Thomas Frank, в силу сохранения свойства на протяжении всей сессии жизни окна / закладки и является необязательным. Для удобства хранения данных я решил использовать структуру&lt;br&gt;ключ1=значение1&amp;ключ2=значение2...ключn=значениеn. Мой маленький набор функций позволяет заменять значения данных, добавлять новые и удалять существующие.&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;| function replaceKey(key, value) {&lt;br&gt;| if(window.name == &#39;&#39; || window.name.indexOf(key) == -1){&lt;br&gt;| alert(&#39;No data in storage saved&#39;)&lt;br&gt;| return;&lt;br&gt;| } &lt;br&gt;| delKey(key);&lt;br&gt;| addKey(key,value);&lt;br&gt;| }&lt;br&gt;| &lt;br&gt;| function addKey(key, value) {&lt;br&gt;| myStorage = window.name;&lt;br&gt;| if(myStorage.indexOf(key+&#39;=&#39;)!= -1) {&lt;br&gt;| alert(&#39;Yet another key&#39;);&lt;br&gt;| return;&lt;br&gt;| }&lt;br&gt;| myStorage += key + &#39;=&#39; + encodeURIComponent(value) +&#39;&amp;&#39;; &lt;br&gt;| window.name = myStorage; &lt;br&gt;| }&lt;br&gt;| &lt;br&gt;| function getKey(key){&lt;br&gt;| if(window.name == &#39;&#39; || window.name.indexOf(key) == -1){&lt;br&gt;| alert(&#39;No data in storage saved&#39;)&lt;br&gt;| return;&lt;br&gt;| }&lt;br&gt;| myStorage = window.name;&lt;br&gt;| temp = myStorage.substring(myStorage.indexOf(key)+key.len gth,myStorage.length);&lt;br&gt;| temp = temp.substring(1,temp.indexOf(&#39;&amp;&#39;));&lt;br&gt;| return temp;&lt;br&gt;| }&lt;br&gt;| &lt;br&gt;| function delKey(key){&lt;br&gt;| if(window.name == &#39;&#39; || window.name.indexOf(key) == -1){&lt;br&gt;| alert(&#39;No data in storage saved&#39;)&lt;br&gt;| return;&lt;br&gt;| } &lt;br&gt;| value = getKey(key);&lt;br&gt;| myStorage = window.name; &lt;br&gt;| rExp = key + &#39;=&#39; + value + &#39;&amp;&#39;;&lt;br&gt;| window.name = myStorage.replace(rExp, &#39;&#39;);&lt;br&gt;| }&lt;br&gt;|&lt;br&gt;| replaceKey (&lt;br&gt;| параметр string key Имя ключа&lt;br&gt;| параметр string value Значение&lt;br&gt;| результат nothing )&lt;br&gt;|&lt;br&gt;| Фунцкция replaceKey удаляет меняет значение ключа на новое.&lt;br&gt;|&lt;br&gt;| addKey (&lt;br&gt;| параметр string key Имя ключа&lt;br&gt;| результат nothing )&lt;br&gt;|&lt;br&gt;| Функция addKey добавляет значение к уже сущестующим.&lt;br&gt;|&lt;br&gt;| delKey (&lt;br&gt;| параметр string key Имя ключа&lt;br&gt;| результат nothing )&lt;br&gt;|&lt;br&gt;| Функция delKey удаляет ключ из массива данных.&lt;br&gt;|&lt;br&gt;| getKey (&lt;br&gt;| параметр string key Имя ключа&lt;br&gt;| результат string temp Значение )&lt;br&gt;|&lt;br&gt;| Функция getKey возвращает значение ключа.&lt;br&gt;| &lt;br&gt;| &lt;html&gt;&lt;br&gt;| &lt;head&gt;&lt;br&gt;| &lt;title&gt;Пример к статье&lt;/title&gt;&lt;br&gt;| &lt;script type=&quot;text/jаvаscript&quot; src=&quot;ex.js&quot;&gt;&lt;/script&gt;&lt;br&gt;| &lt;/head&gt;&lt;br&gt;| &lt;br&gt;| &lt;body&gt;&lt;br&gt;| Hello world&lt;br&gt;| &lt;script type=&quot;text/jаvаscript&quot;&gt;&lt;br&gt;| addKey(&#39;key1&#39;,&#39;value1&#39;);&lt;br&gt;| // window name = key1=value1&amp;&lt;br&gt;| addKey(&#39;key2&#39;,&#39;value2&#39;);&lt;br&gt;| // window name = key1=value1&amp;key2=value2&amp;&lt;br&gt;| delKey(&#39;key2&#39;);&lt;br&gt;| // window name = key1=value1&amp;&lt;br&gt;| replaceKey(&#39;key1&#39;,&#39;newvalue&#39;);&lt;br&gt;| // window name = key1=newvalue&amp;&lt;br&gt;| &lt;/script&gt;&lt;br&gt;| &lt;/body&gt;&lt;br&gt;| &lt;/html&gt;&lt;br&gt;&lt;br&gt;----[ STORAGE ... ]&lt;br&gt;&lt;br&gt;Описание модели, реализующей хранение данных на стороне клиента, появилось в html 5 (http://www.whatwg.org/specs/web-apps/current-work/#storage0).&lt;br&gt;Данный способ является на данный момент самым удобным и даже кроссбраузерным.Люди в w3c представляют структуру storage так&lt;br&gt;&lt;br&gt;&lt;br&gt;Цитата:&lt;br&gt;interface Storage {&lt;br&gt;readonly attribute unsigned long length;&lt;br&gt;[IndexGetter] DOMString key(in unsigned long index);&lt;br&gt;[NameGetter] DOMString getItem(in DOMString key);&lt;br&gt;[NameSetter] void setItem(in DOMString key, in DOMString data);&lt;br&gt;[XXX] void removeItem(in DOMString key); &lt;br&gt;void clear();&lt;br&gt;};&lt;br&gt;&lt;br&gt;&lt;br&gt;Mozilla Firefox предлагает использовать два типа хранилищей - sessionStorage и globalStorage. Первый доступен только на протяжение времени жизни страницы и как только страница закрывается получить доступ к данным уже невозможно. Получить состояние storage можно через dom свойство Dom.storage.enabled&lt;br&gt;&lt;br&gt;| // Сохраняем в sessionStorage переменную username со значением antichat&lt;br&gt;| sessionStorage.username = &quot;antichat&quot;;&lt;br&gt;| // Проверяем, сохранилась ли переменная&lt;br&gt;| alert( &quot;username = &quot; + sessionStorage.username );&lt;br&gt;&lt;br&gt;&lt;br&gt;| // Получаем дескриптор текстового поля &lt;br&gt;| var field = document.getElementById(&quot;field&quot;);&lt;br&gt;| &lt;br&gt;| // Если включен режим автосохранения, загружаем черновик&lt;br&gt;| if ( sessionStorage.autosave ) {&lt;br&gt;| field.value = sessionStorage.autosave;&lt;br&gt;| }&lt;br&gt;| &lt;br&gt;| // Проверяем каждую секунду содержимое текстового поля на изменения&lt;br&gt;| setInterval(function(){&lt;br&gt;| // Сохраняем в черновик&lt;br&gt;| sessionStorage.autosave = field.value;&lt;br&gt;| }, 1000);&lt;br&gt;&lt;br&gt;GlobalStorage позволяет держать данные на протяжение длительного промежутка времени.&lt;br&gt;&lt;br&gt;| // Сохранить переменную snippet в globalStorage только для сайта antichat.ru&lt;br&gt;| globalStorage[&#39;antichat.ru&#39;].snippet = &quot;underWHAT?!&quot;;&lt;br&gt;&lt;br&gt;Счетчик посещения&lt;br&gt;&lt;br&gt;| // parseInt используется для перевода переменной visits в число&lt;br&gt;| // все данные в *Storage хранятся в виде строки&lt;br&gt;| globalStorage[&#39;mozilla.org&#39;].visits =&lt;br&gt;| parseInt( globalStorage[&#39;mozilla.org&#39;].visits || 0 ) + 1;&lt;br&gt;&lt;br&gt;Пример #1 http://aaronboodman.com/halfnote/&lt;br&gt;Пример #2 http://channy.creation.net/work/firefox/domstorage/#&lt;br&gt;&lt;br&gt;Thomas Frank написал библиотеку sessvars, облегчающей работу с globalStorage ( http://www.thomasfrank.se/sessvars.js )&lt;br&gt;&lt;br&gt;Единственная переменная-свойство объекта sessvars, которую вы не должны трогать, это $, потому что она содержит ряд полезных методов:&lt;br&gt;&lt;br&gt;Методы &lt;br&gt;&lt;br&gt;| sessvars.$.clearMem()&lt;br&gt;| Очищает sessvars&lt;br&gt;|&lt;br&gt;| sessvars.$.usedMem()&lt;br&gt;| Возвращает объем используемой памяти в килобайтах&lt;br&gt;|&lt;br&gt;| sessvars.$.usedMemPercent()&lt;br&gt;| Возвращает объем используемой памяти в процентах от общего возможного объема&lt;br&gt;|&lt;br&gt;| sessvars.$.debug()&lt;br&gt;| Выводит окно дебага вверху страницы (как в примере выше)&lt;br&gt;|&lt;br&gt;| sessvars.$.flush()&lt;br&gt;| Явно сохраняет текущее состояние sessvars, так что все данные будут сохранены когда будет совершен переход на другую страницу. Это редко бывает необходимо, так как в нормальной ситуации это делается автоматически при событии unload.&lt;br&gt;&lt;br&gt;Флаги&lt;br&gt;&lt;br&gt;Также есть ряд различных флагов, которыми вы можете устанавливать поведение sessvars:&lt;br&gt;&lt;br&gt;| sessvars.$.prefs.memlimit&lt;br&gt;| По умолчанию - 2000&lt;br&gt;| Указывает объем данных в Кб, разрешенный для хранения в sessvars. По умолчанию 2000 Кб, так как Opera 9.25 имеет ограничение чуть выше этого числа. У остальных браузеров (IE7.0, Firefox 1.5/2.0 и Safari 3.0) ограничение намного выше - 10 Мб не представляют сложности для этих браузеров.&lt;br&gt;&lt;br&gt;| sessvars.$.prefs.autoFlush&lt;br&gt;| true/false, по умолчанию true&lt;br&gt;| Определяет, будет ли метод flush() вызываться автоматически&lt;br&gt;&lt;br&gt;| sessvars.$.prefs.crossDomain&lt;br&gt;| true/false, по умолчанию false&lt;br&gt;| Если флаг установлен в true, содержимое sessvars можно читать из разных доменов (если оба сайта используют sessvars.js).&lt;br&gt;&lt;br&gt;| sessvars.$.prefs.includeFunctions&lt;br&gt;| true/false, по умолчанию false&lt;br&gt;| Определяет, будет ли sessvars сохранять функции.&lt;br&gt;&lt;br&gt;| sessvars.$.prefs.includeProtos&lt;br&gt;| true/false, по умолчанию false&lt;br&gt;| Если true, то будут сохранены свойства, назначенные прототипам различных данных или объектов. Редко бывает необходимо.&lt;br&gt;&lt;br&gt;----[ PersistJS ... ] &lt;br&gt;&lt;br&gt;PersistJS - первая jаvаscript библиотека, которую можно поправу назвать кроссбраузерной ( http://pablotron.org/?cid=1557 )&lt;br&gt;В данный момент он поддерживает следующие механизмы:&lt;br&gt;&lt;br&gt;| Flash 8&lt;br&gt;| Google Gears&lt;br&gt;| localstorage&lt;br&gt;| whatwg_db&lt;br&gt;| globalstorage&lt;br&gt;| UserData (Internet Explorer)&lt;br&gt;| cookie: хранение данных при помощи Cookie.&lt;br&gt;&lt;br&gt;Cookies используются только в случае отсутствия остальных способов.&lt;br&gt;&lt;br&gt;Сохранение данных&lt;br&gt;| // создаем новое хранилище данных&lt;br&gt;| var store = new Persist.Store(&#39;My Data Store&#39;);&lt;br&gt;| &lt;br&gt;| // данные для хранения&lt;br&gt;| var data = &quot;Некая длинная строка ...........&quot;;&lt;br&gt;| &lt;br&gt;| // сохраняем данные&lt;br&gt;| store.set(&#39;saved_data&#39;, data);&lt;br&gt;&lt;br&gt;Получение данных&lt;br&gt;| // получаем данные и показываем их пользователю&lt;br&gt;| store.get(&#39;saved_data&#39;, function(ok, val) { &lt;br&gt;| if (ok)&lt;br&gt;| alert(&#39;saved data = &#39; + val);&lt;br&gt;| }); &lt;br&gt;&lt;br&gt;Удаление данных&lt;br&gt;| store.remove(&#39;saved_data&#39;);&lt;br&gt;&lt;br&gt;Пример #1 http://jstoolbox.com/demo/persistjs/test/test_flash.html&lt;br&gt;&lt;br&gt;----[ OUTRO ... ] &lt;br&gt;&lt;br&gt;При написании статьи были использованы материалы с сайта habrahabr.ru, jstoolbox.com, developer.mozilla.org и msdn.microsoft.com.&lt;br&gt;&lt;br&gt;&lt;br&gt;Надеюсь, что информация не пройдет мимо, потому что эта статья как Ктулху - всё равно рано или поздно придёт и захавает. 2008[/color]</description> 
</item>
<item>
<guid isPermaLink="true">http://scrolls.combats.com/community/~developers/483188.html</guid> 
<pubDate>Fri, 08 May 2009 17:21:00 GMT</pubDate> 
<link>http://scrolls.combats.com/community/~developers/483188.html</link><author>developers : Alex Nomad</author>
<title>Подождите немного и попробуйте ещё раз</title>
<description>Как же мне надоела эта фраза, висящая минутами в бою&lt;br&gt;&quot;&lt;i&gt;&lt;b&gt;Подождите немного и попробуйте ещё раз&lt;/b&gt;&lt;/i&gt;&quot;&lt;br&gt;&lt;br&gt;Самому разбираться почему так ведет себя скрипт боя мне сейчас лень.&lt;br&gt;&lt;br&gt;Поэтому объявляю &lt;b&gt;конкурс&lt;/b&gt; для программистов (и всех кто себя таковыми считает):&lt;br&gt;&lt;br&gt;1) Тому кто разберется в причинах этой баги.&lt;br&gt;2) Тому кто напишет код, исправляющий ее.&lt;br&gt;3) Тому кто первым опубликует правильное описание причин баги и ее исправление в компьюнити Developers&lt;br&gt;&lt;br&gt;От меня будет вручено &lt;b&gt;&lt;font color=&quot;#CD2C28&quot;&gt;20 екр&lt;/font&gt;&lt;/b&gt;.&lt;br&gt;&lt;br&gt;Дерзайте&#33;&lt;br&gt;&lt;br&gt;П.С. Сроки конкурса ограничу 1 июлем, но при необходимости можно и продлить.</description> 
</item>
<item>
<guid isPermaLink="true">http://scrolls.combats.com/community/~developers/445953.html</guid> 
<pubDate>Tue, 24 Mar 2009 01:59:00 GMT</pubDate> 
<link>http://scrolls.combats.com/community/~developers/445953.html</link><author>developers : Damnedest</author>
<title>Получаем инфу из БК</title>
<description>Давным давно &lt;nobr&gt;&lt;A HREF=http://capitalcity.combats.com/clans_inf.pl?Ritter target=_blank&gt;&lt;img src=&quot;http://img.combats.com/i/klan/Ritter.gif&quot; border=0&gt;&lt;/a&gt;&amp;nbsp;&lt;b&gt;Alex Nomad&lt;/b&gt; [9]&lt;a href=&quot;http://capitalcity.combats.com/inf.pl?login=Alex Nomad&quot; target=_blank&gt;&lt;img src=&quot;http://img.combats.com/i/inf.gif&quot; border=0&gt;&lt;/a&gt;&lt;/nobr&gt; &lt;a href=&quot;http://scrolls.combats.com/&#37;7EAlex&#37;20Nomad/9350.html&quot; target=&quot;_blank&quot;&gt;рассказывал&lt;/a&gt; о том, как правильно получать информацию о персонаже в и приводил пример обращения к страницам БК. Мне кажется, что уже давным давно пора начинать использовать ООП, котрое есть в пыхе и использовать &lt;b&gt;православные&lt;/b&gt; методы.&lt;br&gt;&lt;br&gt;Собственно преимущества кода, который я предлагаю:&lt;br&gt; 1. Мы ограничиваем максимальное количество редиректов &lt;u&gt;тремя&lt;/u&gt;. Это не даст возможность серверу БК зациклить наш скрипт.&lt;br&gt;2. Мы ограничиваем время доступа к странице 10 секундами (хотя даже 10 много, лучше 3-5), чтобы не тратить много времени на тормозящий сервер БК.&lt;br&gt;3. Получением данных занимается curl (редиректы, таймауты, правильное разархивация)&lt;br&gt;4. В результате работы, с помощью iconv, мы получаем нормальную UTF-8 строчку, с которой можем спокойно работать. Забудьте вы уже о win-1251 - это архаизм&#33; Надо смотреть в будущее.&lt;br&gt;5. Ну и собственно мы получаем очень хорошие исключение на все ошибки, которые возникнут во время получения данных, которые можно будет отловить и как-то обработать.&lt;br&gt;&lt;br&gt;Код модуля можно посмотреть под катом. Появившиеся вопросы можно оставить в комментах.&lt;br&gt;&lt;br&gt;&lt;?&lt;br&gt;&lt;br&gt;/**&lt;br&gt;.* Класс утилит для работы с БК&lt;br&gt;.*&lt;br&gt;.* @version 0.1&lt;br&gt;.* @author Eugene Reich &lt;eugene.reich@gmail.com&gt;&lt;br&gt;.*/&lt;br&gt;&lt;br&gt;class CombatsUtils&lt;br&gt;{&lt;br&gt;..../**&lt;br&gt;.... * Возвращает содержимое страницы в UTF-8 кодировке&lt;br&gt;.... * Метод анализирует возвращаемые результаты и кидает соответствующие исключения&lt;br&gt;.... *&lt;br&gt;.... * @param string $url&lt;br&gt;.... * @static&lt;br&gt;.... * @access public&lt;br&gt;.... * @return string&lt;br&gt;.... */&lt;br&gt;....&lt;br&gt;....static public function getUrl($url)&lt;br&gt;....{&lt;br&gt;........$ch = curl_init();&lt;br&gt;........&lt;br&gt;........curl_setopt($ch, CURLOPT_URL, $url);&lt;br&gt;........curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);&lt;br&gt;........curl_setopt($ch, CURLOPT_HEADER, 0);&lt;br&gt;........curl_setopt($ch, CURLOPT_TIMEOUT, 10);&lt;br&gt;........curl_setopt($ch, CURLOPT_MAXREDIRS, 3);&lt;br&gt;........curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);&lt;br&gt;........curl_setopt($ch, CURLOPT_FAILONERROR, true);&lt;br&gt;........curl_setopt($ch, CURLOPT_ENCODING, &#39;gzip&#39;);&lt;br&gt;&lt;br&gt;........$result     = curl_exec($ch);&lt;br&gt;........$error      = curl_error($ch);&lt;br&gt;........$error_no   = curl_errno($ch);&lt;br&gt;........&lt;br&gt;........if ($error_no)&lt;br&gt;........{&lt;br&gt;............if ($error_no == 47)&lt;br&gt;...............throw new CombatsUtilsExceptionMaxRedirects();&lt;br&gt;&lt;br&gt;............if ($error_no == 28)&lt;br&gt;................throw new CombatsUtilsExceptionTimeout();&lt;br&gt;&lt;br&gt;............if ($error_no == 7)&lt;br&gt;................throw new CombatsUtilsExceptionConnection();&lt;br&gt;&lt;br&gt;............if ($error_no == 52)&lt;br&gt;................throw new CombatsUtilsExceptionEmpty();&lt;br&gt;&lt;br&gt;............throw new CombatsUtilsExceptionCurl($error_no.&#39;:&#39;.$error);&lt;br&gt;........}&lt;br&gt;&lt;br&gt;........// Меняем кодировку&lt;br&gt;........return iconv(&#39;windows-1251&#39;, &#39;utf-8&#39;, $result);&lt;br&gt;....}&lt;br&gt;}&lt;br&gt;&lt;br&gt;/**&lt;br&gt;.* Базовый класс исключений&lt;br&gt;.*&lt;br&gt;.* @uses NException&lt;br&gt;.* @version 0.1&lt;br&gt;.* @author Eugene Reich &lt;eugene.reich@gmail.com&gt;&lt;br&gt;.*/&lt;br&gt;&lt;br&gt;class CombatsUtilsException extends Exception {}&lt;br&gt;&lt;br&gt;/**&lt;br&gt;.* Превышено максимально допустимое количество редиректов&lt;br&gt;.*&lt;br&gt;.* @uses CombatsUtilsException&lt;br&gt;.* @version 0.1&lt;br&gt;.* @author Eugene Reich &lt;eugene.reich@gmail.com&gt;&lt;br&gt;.*/&lt;br&gt;&lt;br&gt;class CombatsUtilsExceptionMaxRedirects extends CombatsUtilsException {}&lt;br&gt;&lt;br&gt;/**&lt;br&gt;.* Превышен таймаут ожидания ответа от сервера&lt;br&gt;.*&lt;br&gt;.* @uses CombatsUtilsException&lt;br&gt;.* @version 0.1&lt;br&gt;.* @author Eugene Reich &lt;eugene.reich@gmail.com&gt;&lt;br&gt;.*/&lt;br&gt;&lt;br&gt;class CombatsUtilsExceptionTimeout extends CombatsUtilsException {}&lt;br&gt;&lt;br&gt;/**&lt;br&gt;.* Не удалось установить соединение с сервером&lt;br&gt;.*&lt;br&gt;.* @uses CombatsUtilsException&lt;br&gt;.* @version 0.1&lt;br&gt;.* @author Eugene Reich &lt;eugene.reich@gmail.com&gt;&lt;br&gt;.*/&lt;br&gt;&lt;br&gt;class CombatsUtilsExceptionConnection extends CombatsUtilsException {}&lt;br&gt;&lt;br&gt;/**&lt;br&gt;.* Пришел пустой ответ&lt;br&gt;.*&lt;br&gt;.* @uses CombatsUtilsException&lt;br&gt;.* @version 0.1&lt;br&gt;.* @author Eugene Reich &lt;eugene.reich@gmail.com&gt;&lt;br&gt;.*/&lt;br&gt;&lt;br&gt;class CombatsUtilsExceptionEmpty extends CombatsUtilsException {}&lt;br&gt;&lt;br&gt;/**&lt;br&gt;.* Непредусмотренное исключение&lt;br&gt;.*&lt;br&gt;.* @uses CombatsUtilsException&lt;br&gt;.* @version 0.1&lt;br&gt;.* @author Eugene Reich &lt;eugene.reich@gmail.com&gt;&lt;br&gt;.*/&lt;br&gt;&lt;br&gt;class CombatsUtilsExceptionCurl extends CombatsUtilsException {}</description> 
</item>
<item>
<guid isPermaLink="true">http://scrolls.combats.com/community/~developers/444135.html</guid> 
<pubDate>Sat, 21 Mar 2009 22:08:00 GMT</pubDate> 
<link>http://scrolls.combats.com/community/~developers/444135.html</link><author>developers : Damnedest</author>
<title>Кеш спасет мир&#33;</title>
<description>В блоге очень много было рассказов о том, как написать какой-то функционал и как что-то ускорить. Конечно, все этого, очень здорово, но мне кажется сообщество не совсем понимает, что этими постами оно дает в руки бомбу замедленного действия будущим программерам клановых сайтов (как показывает практика сервер БК можно положить обычной ссылкой на полный лог великой :boks2:).&lt;br&gt;&lt;br&gt;По моим наблюдения в БК очень мало сильных программистов, тех, которые имеют за плечами проекты не в 200-300 хостов в сутки, а у которых есть сайты, на которых одновременно находится несколько десятков тысяч человек. Я бы хотел в этом посте затронуть тему оптимизации сайта под высокие нагрузки.&lt;br&gt;&lt;br&gt;В БК о высоких нагрузках кроме некоторых кланов никто и не задумывался, а те, кто с этим сталкивались решали ее просто - покупали более мощные сервер или переходили на новый тарифный план. Некоторые пытались запретить очень частые запросы пользователей на сайт, последовав по стопам БК, хотя в большинстве случаев необходимости не было.&lt;br&gt;&lt;br&gt;Я видел некоторые клановые сайты, на которых при выводе ника автора новости, происходило обращение к информации о персонаже БК. Это п****ц и так делать нельзя. Если вы так сделали - убейтесь пожалуйста. Спасибо.&lt;br&gt;&lt;br&gt;Я видел, как писали вывод состава на PHP, когда по крону раз в 5 минут запускался скрипт и вытягивал инфу о персонаже, чтобы получить его оналайн. Вы правда думаете, что у сокланов нет кнопочки в БК, в которой можно посмотреть весь состав? А может вы решили сделать доброе дело для тех, кто хочет отрабатывать по вашему клану ЧС? А может вы думаете, что нуб 8 левела, который зайдет к вам на сайт и посмотрит ваш состав будет сильно переживать из-за того, что не увидит кого-нить в онлайне? Не смешите.&lt;br&gt;&lt;br&gt;Что делать? Все просто - надо &lt;b&gt;думать&lt;/b&gt;&#33;&lt;br&gt;&lt;br&gt;1. Думаем куда делать запрос. Если персонаж при последнем обновлении состава находился в Столице, то с вероятностью около 70&#37; он и щас будет находится там же (вероятность не придумана, это реальная цифра). Таким вот простым способом мы уменьшили нагрузку на сервер.&lt;br&gt;2. Между запросами к БК надо делать задержку. 2-5 секунд примерно, чтобы не мучать ни БК, ни свой сервер (например скрипт получения состава просто в цикле делал запросы, из-за чего раз в 5 минут на сервере наблюдалась некоторая заторможенность).&lt;br&gt;3. Кешируйте запросы. Зачем каждый раз делать запрос к базе на получение состава, если вы знаете, что скрипт обновления у вам работает раз в пол часа? Получите данные из базы и сохраните их в файле. И следующие пол часа получайте инфу из файла. Да, тут вам придется думать. Если это будет интересно, я могу рассказать как реализовать грамотное кеширование в мемкешед или в обычных файлах )&lt;br&gt;4. Кешируйте не только данные, но и html. Для вывода состава клана серверу требуется произвести достаточно большое количество обращений к шаблонам. Проще закешировать html с составом клана и отдавать его. Ускорение будет реальное.&lt;br&gt;&lt;br&gt;Вообще есть еще множество различных оптимизаций, которые может сделать каждый клановый сайт, сталкивающийся с нагрузкой, но это уже индивидуально.&lt;br&gt;&lt;br&gt;P.S. Думайте, что делаете!&lt;br&gt;P.P.S. И не делайте всякий бред типа ограничения запросов с одного IP. Лучше займитесь оптимизайией.</description> 
</item>
<item>
<guid isPermaLink="true">http://scrolls.combats.com/community/~developers/360968.html</guid> 
<pubDate>Sat, 15 Nov 2008 05:16:00 GMT</pubDate> 
<link>http://scrolls.combats.com/community/~developers/360968.html</link><author>developers : СэрАртём</author>
<title>Ускоряем jаvаscript</title>
<description>Нередко перед web-разработчиками встаёт проблема низкой производительности клиентского кода, обычно реализуемого на jаvаscript. В этот момент можно услышать кучу нелестных отзывов как в адрес тех, кто поставил такую задачу, так и и в адрес тех, кто реализовал ту или иную версию jаvаscript, и даже в адрес самого языка. Однако, тут поговорка &quot;нечего на зеркало пенять, если рожа кривая&quot; подходит, как нельзя кстати. Посмотрим на наглядном примере. [cut &quot;Далее&quot;]Задача: динамически сгенерировать на клиенте HTML-документ с кнопками, впоследствии которым будут назначены обработчики событий. Приблизительно поставленную задачу можно решить так:&lt;br&gt;&lt;br&gt;&lt;i&gt;&lt;script&gt;&lt;br&gt;var count = 500;&lt;br&gt;&lt;br&gt;var log = [];&lt;br&gt;function clicked(e) {&lt;br&gt; 	e = e || window.event;&lt;br&gt; 	log.push((e.srcElement || e.target).id);&lt;br&gt;}&lt;br&gt;&lt;br&gt;function run() {&lt;br&gt; 	for(var i=0; i&lt;count; i--) {&lt;br&gt; 	 	var button = document.createElement(&#39;button&#39;);&lt;br&gt; 	 	button.id = &#39;item&#39;+i;&lt;br&gt; 	 	document.body.insertBefore(button, null);&lt;br&gt; 	}&lt;br&gt;&lt;br&gt; 	for(var i=0; i&lt;count; i--) {&lt;br&gt; 	 	document.getElementById(&#39;item&#39;+i).onclick = clicked;&lt;br&gt; 	}&lt;br&gt;&lt;br&gt; 	for(var i=0; i&lt;count; i--) {&lt;br&gt; 	 	document.getElementById(&#39;item&#39;+i).click();&lt;br&gt; 	}&lt;br&gt;}&lt;br&gt;&lt;br&gt;run();&lt;br&gt;&lt;/script&gt;&lt;/i&gt;&lt;br&gt;&lt;br&gt;Казалось бы - что проще? Ан, нет: корявость IE (даже 8й версии) приводит к тому, что двойной вызов &lt;i&gt;document.getElementById(&#39;item&#39;+i)&lt;/i&gt; оказывается самой длительной операцией, отнимающей более 90&#37; всего времени. В Opera и Mozilla эта операция реализована аккуратнее и потери не так заметны. Попробуем ускорить код, введя кэш элементов:&lt;br&gt;&lt;br&gt;&lt;i&gt;function run() {&lt;br&gt; 	for(var i=0; i&lt;count; i--) {&lt;br&gt; 	 	var button = document.createElement(&#39;button&#39;);&lt;br&gt; 	 	button.id = &#39;item&#39;+i;&lt;br&gt; 	 	cache[&#39;item&#39;+i] = document.body.insertBefore(button, null);&lt;br&gt; 	}&lt;br&gt;&lt;br&gt; 	for(var i=0; i&lt;count; i--) {&lt;br&gt; 	 	cache[&#39;item&#39;+i].onclick = clicked;&lt;br&gt; 	}&lt;br&gt;&lt;br&gt; 	for(var i=0; i&lt;count; i--) {&lt;br&gt; 	 	cache[&#39;item&#39;+i].click();&lt;br&gt; 	}&lt;br&gt;}&lt;/i&gt;&lt;br&gt;&lt;br&gt;Вот мы и избавились от ненужных вызовов функции &lt;i&gt;getElementById&lt;/i&gt;. Но что делать, если содержимое документа генерируется на стороне клиента не полностью, а частично? Путей решения два: обойти дерево элементов документа или динамически заполнять кэш. Вот как это реализуется:&lt;br&gt;&lt;br&gt;&lt;i&gt;var cache;&lt;br&gt;/* Использование кэша, заполняющегося полным обходом дерева элементов HTML-документа */&lt;br&gt;var getElement = function (id) {&lt;br&gt; 	cache = {};&lt;br&gt; 	function cacheItems(element) {&lt;br&gt; 	 	if (&#33;(&#39;childNodes&#39; in element))&lt;br&gt; 	 	 	return;&lt;br&gt; 	 	for(var i=0; i&lt;element.childNodes.length; i++) {&lt;br&gt; 	 	 	if (element.childNodes[ i ].id)&lt;br&gt; 	 	 	 	cache[element.childNodes[ i ].id] = element.childNodes[ i ];&lt;br&gt; 	 	 	cacheItems(element.childNodes[ i ]);&lt;br&gt; 	 	}&lt;br&gt; 	}&lt;br&gt; 	cacheItems(document.body);&lt;br&gt; 	getElement = function(id) {&lt;br&gt; 	 	return cache[id];&lt;br&gt; 	}&lt;br&gt; 	return getElement(id);&lt;br&gt;}&lt;br&gt;&lt;br&gt;function run() {&lt;br&gt;//  ...&lt;br&gt; 	for(var i=0; i&lt;count; i--) {&lt;br&gt; 	 	getElement(&#39;item&#39;+i).onclick = clicked;&lt;br&gt; 	}&lt;br&gt;//  ...&lt;br&gt;}&lt;/i&gt;&lt;br&gt;&lt;br&gt;В примере хорошо видно, что переменная &lt;i&gt;getElement&lt;/i&gt;, являющаяся функцией, при первом же вызове рекурсивно обходит дерево элементов документа, заполняя кэш всеми элементами, имеющими идентификатор, а по завершению обхода принимает другое значение, при последующих вызовах возврашая содержимое кэша.&lt;br&gt;&lt;br&gt;&lt;i&gt;var cache;&lt;br&gt;/* Использование кэша, заполняющегося по запросу */&lt;br&gt;getElement = function(id) {&lt;br&gt; 	cache = {};&lt;br&gt; 	getElement = function(id) {&lt;br&gt; 	 	return cache[id] || (cache[id]=document.getElementById(id));&lt;br&gt; 	}&lt;br&gt; 	return getElement(id);&lt;br&gt;}&lt;/i&gt;&lt;br&gt;&lt;br&gt;Здесь при первом вызове переменной-функции сбрасывается кэш, а при последующих вызовах возвращается содержимое кэша (если оно там есть), либо производится заполнение кэша путём вызова &lt;i&gt;getElementById&lt;/i&gt; и возврат полученного значения.&lt;br&gt;&lt;br&gt;Отдельного рассмотрения требует обработчик события &lt;i&gt;clicked(e)&lt;/i&gt;. Из-за разной реализации генерируемых событий пришлось писать достаточно некрасивый и непроизводительный код. Можно ли сделать его проще? Можно! Вот так:&lt;br&gt;&lt;br&gt;&lt;i&gt;/* Не привязанный к какому-либо браузеру динамически генерируемый обработчик */&lt;br&gt;function generateClicked(element) {&lt;br&gt; 	return function() {&lt;br&gt; 	 	log.push(element.id);&lt;br&gt; 	}&lt;br&gt;}&lt;br&gt;&lt;br&gt;function run() {&lt;br&gt;// ...&lt;br&gt; 	for(var i=0; i&lt;count; i--) {&lt;br&gt; 	 	getElement(&#39;item&#39;+i).onclick = generateClicked(getElement(&#39;item&#39;+i));&lt;br&gt; 	}&lt;br&gt;// ...&lt;br&gt;}&lt;/i&gt;&lt;br&gt;&lt;br&gt;Что происходит в этом примере? Для каждого элемента вызывается функция, которая порождает объект-функцию с уже инициализированной переменной &lt;i&gt;element&lt;/i&gt;. В результате при нажатии на кнопку будет вызвана её личная функция, в которой &lt;i&gt;element&lt;/i&gt; указывает именно на эту кнопку. Нет необходимости использовать объект &quot;событие&quot; (разумеется, если в обработчике не нужны специфические свойства события, как то: координаты мыши во время клика, состояние клавиши Ctrl и прочее...), нет необходимости адаптировать код для нескольких браузеров, обработка события выполняется быстрее.&lt;br&gt;&lt;br&gt;Ниже приведён полный код файла для игр с &quot;ускорением&quot;. &lt;div id=&quot;s_47999468_2&quot; style=&quot;display:&quot;&gt;&lt;a href=&quot;#&quot; onClick=&quot;document.all.s_47999468_2.style.display=&#39;none&#39;; document.all.s_47999468_1.style.display=&#39;&#39;;return false;&quot;&gt;[&#37;param.l.filters.Show&#37;]&lt;/a&gt;&lt;/div&gt;&lt;div id=&quot;s_47999468_1&quot; style=&quot;display:none&quot;&gt;&lt;a href=&quot;#&quot; onClick=&quot;document.all.s_47999468_1.style.display=&#39;none&#39;; document.all.s_47999468_2.style.display=&#39;&#39;;return false;&quot;&gt;[&#37;param.l.filters.Hide&#37;]&lt;/a&gt;&lt;br/&gt;&lt;i&gt;&lt;html&gt;&lt;br&gt;&lt;br&gt;&lt;head&gt;&lt;br&gt;&lt;title&gt;Замер производительности браузера&lt;/title&gt;&lt;br&gt;&lt;br&gt;&lt;script&gt;&lt;br&gt;&lt;br&gt;var timer = {&lt;br&gt; 	time: null,&lt;br&gt; 	interval: 0,&lt;br&gt; 	Start: function() {&lt;br&gt; 	 	this.time = new Date();&lt;br&gt; 	},&lt;br&gt; 	Stop: function() {&lt;br&gt; 	 	return this.interval = (new Date()).valueOf() - this.time.valueOf();&lt;br&gt; 	}&lt;br&gt;}&lt;br&gt;&lt;br&gt;/* Использование классического getElementById */&lt;br&gt;function getElement1(id) {&lt;br&gt; 	return document.getElementById(id);&lt;br&gt;}&lt;br&gt;&lt;br&gt;/* Использование document.all, присущего только IE */&lt;br&gt;function getElement2(id) {&lt;br&gt; 	return document.all[id];&lt;br&gt;}&lt;br&gt;&lt;br&gt;var cache = null;&lt;br&gt;&lt;br&gt;/* Использование кэша, заполняющегося полным обходом дерева элементов HTML-документа */&lt;br&gt;function getElement3(id) {&lt;br&gt; 	cache = {};&lt;br&gt; 	function cacheItems(element) {&lt;br&gt; 	 	var currentElement = element.firstChild;&lt;br&gt; 	 	while (currentElement) {&lt;br&gt; 	 	 	if (currentElement.id)&lt;br&gt; 	 	 	 	cache[currentElement.id] = currentElement;&lt;br&gt; 	 	 	if (currentElement.firstChild)&lt;br&gt; 	 	 	 	cacheItems(currentElement);&lt;br&gt; 	 	 	currentElement = currentElement.nextSibling;&lt;br&gt; 	 	}&lt;br&gt; 	}&lt;br&gt; 	cacheItems(document.body);&lt;br&gt; 	getElement = function(id) {&lt;br&gt; 	 	return cache[id];&lt;br&gt; 	}&lt;br&gt; 	return getElement(id);&lt;br&gt;}&lt;br&gt;&lt;br&gt;/* Использование кэша, заполняющегося по запросу */&lt;br&gt;function getElement4(id) {&lt;br&gt; 	cache = {};&lt;br&gt; 	getElement = function(id) {&lt;br&gt; 	 	return cache[id] || (cache[id]=document.getElementById(id));&lt;br&gt; 	}&lt;br&gt; 	return getElement(id);&lt;br&gt;}&lt;br&gt;&lt;br&gt;/* Выбор способа доступа к элементам HTML-документа */&lt;br&gt;var getElement = getElement1;&lt;br&gt;&lt;br&gt;var log = [];&lt;br&gt;&lt;br&gt;/* Универсальный для всех браузеров обработчик события */&lt;br&gt;function clicked(e) {&lt;br&gt; 	e = e || window.event;&lt;br&gt; 	log.push((e.srcElement || e.target).id);&lt;br&gt;}&lt;br&gt;&lt;br&gt;/* Не привязанный к какому-либо браузеру динамически генерируемый обработчик */&lt;br&gt;function generateClicked(element) {&lt;br&gt; 	return function() {&lt;br&gt; 	 	log.push(element.id);&lt;br&gt; 	}&lt;br&gt;}&lt;br&gt;&lt;br&gt;var STYLE_DISPLAY = &#39;&#39;;&lt;br&gt;&lt;br&gt;function createElements(parent, count, level) {&lt;br&gt; 	for(var i=0; i&lt;5 &amp;&amp; count&gt;=0; i--, count--) {&lt;br&gt; 	 	var button = document.createElement(&#39;button&#39;);&lt;br&gt; 	 	button.id = &#39;item&#39;+count;&lt;br&gt; 	 	button.style.display = STYLE_DISPLAY;&lt;br&gt; 	 	parent.insertBefore(button, null);&lt;br&gt; 	}&lt;br&gt; 	if (level&lt;5 &amp;&amp; count&gt;=0) {&lt;br&gt; 	 	var span = document.createElement(&#39;span&#39;);&lt;br&gt; 	 	span.style.display = STYLE_DISPLAY;&lt;br&gt; 	 	createElements(&lt;br&gt; 	 	 	parent.insertBefore(span, null),&lt;br&gt; 	 	 	count,&lt;br&gt; 	 	 	level+1);&lt;br&gt; 	}&lt;br&gt;}&lt;br&gt;&lt;br&gt;var COUNT = 3000;&lt;br&gt;function test() {&lt;br&gt;&lt;br&gt; 	timer.Start();&lt;br&gt;/* Наполнение HTML-документа &quot;на лету&quot;, генерация дерева объектов */&lt;br&gt; 	createElements(document.body, COUNT-1, 0);&lt;br&gt; 	var createTime = timer.Stop();&lt;br&gt;&lt;br&gt; 	timer.Start();&lt;br&gt; 	for(var i=0; i&lt;COUNT; i++) {&lt;br&gt;/* Одна из следующих двух строк должна быть закомментирована */&lt;br&gt;/* Выбор способа доступа к объекту, сгенерировавшему событие */&lt;br&gt; 	 	getElement(&#39;item&#39;+i).onclick = clicked;&lt;br&gt;// 	 	var element = getElement(&#39;item&#39;+i); element.onclick = generateClicked(element);&lt;br&gt; 	}&lt;br&gt; 	var initTime = timer.Stop();&lt;br&gt;&lt;br&gt; 	timer.Start();&lt;br&gt;/* Изменение свойства объекта. Генерируется событие onpropertychange */&lt;br&gt; 	for(var i=0; i&lt;COUNT; i++) {&lt;br&gt; 	 	getElement(&#39;item&#39;+i).click();&lt;br&gt; 	}&lt;br&gt; 	var eventsTime = timer.Stop();&lt;br&gt; 	&lt;br&gt; 	alert(createTime+&#39;, &#39;+initTime+&#39;, &#39;+eventsTime);&lt;br&gt;}&lt;br&gt;&lt;br&gt;&lt;/script&gt;&lt;br&gt;&lt;br&gt;&lt;/head&gt;&lt;br&gt;&lt;br&gt;&lt;body onload=&quot;test()&quot;&gt;&lt;br&gt;&lt;/body&gt;&lt;br&gt;&lt;br&gt;&lt;/html&gt;&lt;/i&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;Можно менять значение переменной &lt;i&gt;getElement&lt;/i&gt; на одну из функций &lt;i&gt;getElement1&lt;/i&gt;, &lt;i&gt;getElement2&lt;/i&gt;, &lt;i&gt;getElement3&lt;/i&gt; или &lt;i&gt;getElement4&lt;/i&gt;. В Mozilla и в Opera &lt;i&gt;getElement2&lt;/i&gt; будет вызывать ошибку, потому что доступ методом &lt;i&gt;document.all&lt;/i&gt; - нестандартный и реализован только в IE. &lt;br&gt;Также можно комментировать одну из строк выбора способа доступа к объекту, сгенерировавшему событие.&lt;br&gt;&lt;br&gt;Надеюсь, мои подсказки помогут специалистам в будущем избежать головной боли ;)[/cut]&lt;br&gt;&lt;br&gt;&lt;b&gt;Update: 17-11-08 17:15&lt;/b&gt;&lt;br&gt;Как выяснилось, разные версии IE по-разному обрабатывают способы обращения к элемементам документа. Я немного изменил последний пример для того, чтобы заполняющийся полным обходом дерева элементов кэш работал с одинаковой производительностью на IE6-IE8&lt;br&gt;&lt;br&gt;&lt;b&gt;Update: 17-02-09 15:45&lt;/b&gt;&lt;br&gt;К слову о производительности: &lt;a href=&quot;http://www.realcoding.net/article/view/6905&quot; target=&quot;_blank&quot;&gt;Производительность простых и сложных конструкций в jаvаscript&lt;/a&gt; от RealCoding.NET</description> 
</item>
<item>
<guid isPermaLink="true">http://scrolls.combats.com/community/~developers/349770.html</guid> 
<pubDate>Fri, 31 Oct 2008 16:40:00 GMT</pubDate> 
<link>http://scrolls.combats.com/community/~developers/349770.html</link><author>developers : СэрАртём</author>
<title>Призраки Бойцовского Клуба</title>
<description>Баги ходють по БК, их видать издалека. Предлагаю (и буду неоригинален) собрать баги в одну кучу. Правило добавления очень простое: описать исходные условия и последовательность действий для воспроизведения бага. Если баг не требует воспроизведения, а очевиден - указывается фрагмент кода, ответственный за баг. Сообщения вида &quot;вчера был в БК - вещь была, сегодня зашёл - её нет&quot; не катит. Нужно чёткое описание, при каких условиях и действиях пропала вещь.&lt;br&gt;&lt;br&gt;Далее идут потверждённые баги.&lt;br&gt;&lt;br&gt;При отправке в чат сообщения, содержащего символы кириллицы и URL-encoded символы в кодировке UTF-8, первые заменяются на знаки &quot;?&quot;, а последние отображаются в decoded виде. &lt;div id=&quot;s_45977300_2&quot; style=&quot;display:&quot;&gt;&lt;a href=&quot;#&quot; onClick=&quot;document.all.s_45977300_2.style.display=&#39;none&#39;; document.all.s_45977300_1.style.display=&#39;&#39;;return false;&quot;&gt;Как воспроизвести&lt;/a&gt;&lt;/div&gt;&lt;div id=&quot;s_45977300_1&quot; style=&quot;display:none&quot;&gt;&lt;a href=&quot;#&quot; onClick=&quot;document.all.s_45977300_1.style.display=&#39;none&#39;; document.all.s_45977300_2.style.display=&#39;&#39;;return false;&quot;&gt;Скрыть&lt;/a&gt;&lt;br/&gt;Если отправить сообщение &quot;Читайте скролл: http://scrolls.combats.com/~&#37;D0&#37;92&#37;D0&#37;BE&#37;D0&#37;BB&#37;D1&#37;8B&#37;D0&#37;BD&#37;D1&#37;89&#37;D0&#37;B8&#37;D0&#37;BA&quot; то в чате будет отображено: &quot;??????? ??????: http://scrolls.combats.com/~Волынщик&quot;&lt;/div&gt;&lt;br&gt;Ошибка jаvаscript при отображении custom hint при наведении указателя на количество предметов в пачке. &lt;div id=&quot;s_85664508_2&quot; style=&quot;display:&quot;&gt;&lt;a href=&quot;#&quot; onClick=&quot;document.all.s_85664508_2.style.display=&#39;none&#39;; document.all.s_85664508_1.style.display=&#39;&#39;;return false;&quot;&gt;Как воспроизвести&lt;/a&gt;&lt;/div&gt;&lt;div id=&quot;s_85664508_1&quot; style=&quot;display:none&quot;&gt;&lt;a href=&quot;#&quot; onClick=&quot;document.all.s_85664508_1.style.display=&#39;none&#39;; document.all.s_85664508_2.style.display=&#39;&#39;;return false;&quot;&gt;Скрыть&lt;/a&gt;&lt;br/&gt;Открыть инвентарь в разделе, где есть группированные предметы. Навести указатель мыши на количество предметов в пачке (например, &quot;x99&quot;). В строке статуса появляется сообщение об ошибке jаvаscript: &#39;ls***&#39; is undefined. Проблема связана с реализацией торговой панели, где всплывающая подсказка содержит полную информацию о премете. Лечится путём удаления атрибутов &lt;b&gt;onmouseover&lt;/b&gt; и &lt;b&gt;onmouseout&lt;/b&gt; у элемента &lt;small&gt;&lt;/small&gt;&lt;/div&gt;&lt;br&gt;Ошибка вёрстки списка заявок в групповых поединках, приводящая к разрушению структуры документа. &lt;div id=&quot;s_7310917_2&quot; style=&quot;display:&quot;&gt;&lt;a href=&quot;#&quot; onClick=&quot;document.all.s_7310917_2.style.display=&#39;none&#39;; document.all.s_7310917_1.style.display=&#39;&#39;;return false;&quot;&gt;Детали&lt;/a&gt;&lt;/div&gt;&lt;div id=&quot;s_7310917_1&quot; style=&quot;display:none&quot;&gt;&lt;a href=&quot;#&quot; onClick=&quot;document.all.s_7310917_1.style.display=&#39;none&#39;; document.all.s_7310917_2.style.display=&#39;&#39;;return false;&quot;&gt;Скрыть&lt;/a&gt;&lt;br/&gt;&lt;br&gt;Каждая заявка разделена на левую и правую стороны следующим HTML-фрагментом, в котором нарушена вложенность: &lt;font class=dsc&gt;&lt;i&gt;против&lt;/font&gt;&lt;/i&gt;&lt;/div&gt;&lt;br&gt;В Internet Explorer 8 не отображается список игроков, находящихся в комнате. &lt;div id=&quot;s_57320267_2&quot; style=&quot;display:&quot;&gt;&lt;a href=&quot;#&quot; onClick=&quot;document.all.s_57320267_2.style.display=&#39;none&#39;; document.all.s_57320267_1.style.display=&#39;&#39;;return false;&quot;&gt;Детали&lt;/a&gt;&lt;/div&gt;&lt;div id=&quot;s_57320267_1&quot; style=&quot;display:none&quot;&gt;&lt;a href=&quot;#&quot; onClick=&quot;document.all.s_57320267_1.style.display=&#39;none&#39;; document.all.s_57320267_2.style.display=&#39;&#39;;return false;&quot;&gt;Скрыть&lt;/a&gt;&lt;br/&gt;В функции &lt;i&gt;wu(inv,name,id,align,klan,level,slp,trv,city,att,private,afk,afk_text,dnd,dnd_text,bat,ill,sms)&lt;/i&gt; в окне списка игроков комнаты (http://dreamscity.combats.com/buttons.pl?list=) используется переменная &lt;b&gt;opener&lt;/b&gt;, которая не инициализируется как локальная, а фактически является членом объекта window, что вызывает отказ во всех правильных браузерах (в том числе, IE8).&lt;/div&gt;&lt;br&gt;Ошибка объявления функций в top-level окне, приводящая к несовместимости с браузерами, отличными, от IE.&lt;div id=&quot;s_81365957_2&quot; style=&quot;display:&quot;&gt;&lt;a href=&quot;#&quot; onClick=&quot;document.all.s_81365957_2.style.display=&#39;none&#39;; document.all.s_81365957_1.style.display=&#39;&#39;;return false;&quot;&gt;Детали&lt;/a&gt;&lt;/div&gt;&lt;div id=&quot;s_81365957_1&quot; style=&quot;display:none&quot;&gt;&lt;a href=&quot;#&quot; onClick=&quot;document.all.s_81365957_1.style.display=&#39;none&#39;; document.all.s_81365957_2.style.display=&#39;&#39;;return false;&quot;&gt;Скрыть&lt;/a&gt;&lt;br/&gt;Имя идентификатора, в том числе, функции, не должно содержить специальных символов, в частности, точку (&quot;.&quot;). Однако, изменения, связанные с внедрением панели быстрого доступа, содержат ряд объявлений функций вида&lt;br&gt;&lt;i&gt;function top.OnUse(what) {&lt;br&gt;...&lt;br&gt;}&lt;/i&gt;&lt;br&gt;Правильно добавлять члены top-level окну так:&lt;br&gt;&lt;i&gt;top.OnUse = function (what) {&lt;br&gt;...&lt;br&gt;}&lt;/i&gt;&lt;br&gt;&lt;/div&gt;&lt;br&gt;При подтормаживании канала возможно неоднократное появление в чате своего сообщения или сообщений других участников чата&lt;div id=&quot;s_14605045_2&quot; style=&quot;display:&quot;&gt;&lt;a href=&quot;#&quot; onClick=&quot;document.all.s_14605045_2.style.display=&#39;none&#39;; document.all.s_14605045_1.style.display=&#39;&#39;;return false;&quot;&gt;Детали&lt;/a&gt;&lt;/div&gt;&lt;div id=&quot;s_14605045_1&quot; style=&quot;display:none&quot;&gt;&lt;a href=&quot;#&quot; onClick=&quot;document.all.s_14605045_1.style.display=&#39;none&#39;; document.all.s_14605045_2.style.display=&#39;&#39;;return false;&quot;&gt;Скрыть&lt;/a&gt;&lt;br/&gt;В функции &lt;i&gt;AjaxLoad(url, fun)&lt;/i&gt; производится проверка на факт отправки сообщения:&lt;br&gt;&lt;i&gt;if (AjaxBegin) return 0;&lt;/i&gt;&lt;br&gt;Однако, значение AjaxBegin сбрасывается в 0 через 1 секунду после отправки сообщения, не зависимо от результата отправки:&lt;br&gt;&lt;i&gt;ab = setTimeout(&#39;AjaxBegin = 0&#39;,1000);&lt;/i&gt;&lt;br&gt;Как следствие, на загруженном канале возможно инициирование нового соединения, пока открыто старое. В реализации объекта &lt;b&gt;XMLHttpRequest&lt;/b&gt; от Microsoft есть один прикол: он может открывать несколько соединений одновременно, но обработчик события &lt;b&gt;onreadystatechange&lt;/b&gt; будет только один и свойство &lt;b&gt;readyState&lt;/b&gt; будет возвращать статус только первого соединения. В результате, на каждый пакет, приходящий после повторной отправки сообщений, в чат будет кидаться пачка сообщений, принятая по первому запросу. Баг лечится путём повторного создания объекта &lt;b&gt;req&lt;/b&gt;&lt;/div&gt;&lt;br&gt;Зависание статистики боя, проведённого в Изломе Хаоса.&lt;div id=&quot;s_46236381_2&quot; style=&quot;display:&quot;&gt;&lt;a href=&quot;#&quot; onClick=&quot;document.all.s_46236381_2.style.display=&#39;none&#39;; document.all.s_46236381_1.style.display=&#39;&#39;;return false;&quot;&gt;Как воспроизвести&lt;/a&gt;&lt;/div&gt;&lt;div id=&quot;s_46236381_1&quot; style=&quot;display:none&quot;&gt;&lt;a href=&quot;#&quot; onClick=&quot;document.all.s_46236381_1.style.display=&#39;none&#39;; document.all.s_46236381_2.style.display=&#39;&#39;;return false;&quot;&gt;Скрыть&lt;/a&gt;&lt;br/&gt;После того, как завершён бой в Изломе Хаоса, его статистика (количество убитых ботов) будет отображаться на любой другой страничке боя Abbadon&#39;а. Помогает только перезагрузка окна БК.&lt;/div&gt;&lt;br&gt;Ошибка в кодировке при поиске в аукционе&lt;div id=&quot;s_54192185_2&quot; style=&quot;display:&quot;&gt;&lt;a href=&quot;#&quot; onClick=&quot;document.all.s_54192185_2.style.display=&#39;none&#39;; document.all.s_54192185_1.style.display=&#39;&#39;;return false;&quot;&gt;Как воспроизвести&lt;/a&gt;&lt;/div&gt;&lt;div id=&quot;s_54192185_1&quot; style=&quot;display:none&quot;&gt;&lt;a href=&quot;#&quot; onClick=&quot;document.all.s_54192185_1.style.display=&#39;none&#39;; document.all.s_54192185_2.style.display=&#39;&#39;;return false;&quot;&gt;Скрыть&lt;/a&gt;&lt;br/&gt;1) в поле &quot;Имя&quot; вводим фразу &quot;Сущность ресурса&quot;&lt;br&gt;2) делаем ставку на один из найденных лотов&lt;br&gt;3) в поле &quot;Имя&quot; теперь вписано &quot;&#37;D1&#37;F3&#37;F9&#37;ED&#37;EE&#37;F1&#37;F2&#37;FC+&#37;F0&#37;E5&#37;F1&#37;F3&#37;F0&#37;F1&#37;E0&quot; и, соответственно, пропали предложения. Необходимо заново вписать в поле &quot;Имя&quot; название искомого предмета и снова сделать поиск.&lt;/div&gt;&lt;br&gt;100&#37; загрузка процессора при наведении на телепортатор в зале ожидания. &lt;div id=&quot;s_83739236_2&quot; style=&quot;display:&quot;&gt;&lt;a href=&quot;#&quot; onClick=&quot;document.all.s_83739236_2.style.display=&#39;none&#39;; document.all.s_83739236_1.style.display=&#39;&#39;;return false;&quot;&gt;Детали&lt;/a&gt;&lt;/div&gt;&lt;div id=&quot;s_83739236_1&quot; style=&quot;display:none&quot;&gt;&lt;a href=&quot;#&quot; onClick=&quot;document.all.s_83739236_1.style.display=&#39;none&#39;; document.all.s_83739236_2.style.display=&#39;&#39;;return false;&quot;&gt;Скрыть&lt;/a&gt;&lt;br/&gt;Объект с &lt;i&gt;id=central_port&lt;/i&gt; имеет обработчик события &lt;i&gt;onmousemove&lt;/i&gt;. Это событие генерируется не только в тот момент, когда указатель мыши попадает в границы объекта, а непрерывно, пока указатель мыши находится в границах объекта. Правильно было бы инициализировать обработчик события &lt;i&gt;onmouseover&lt;/i&gt;, а &lt;i&gt;onmousemove&lt;/i&gt; удалить.&lt;/div&gt;</description> 
</item>
<item>
<guid isPermaLink="true">http://scrolls.combats.com/community/~developers/74715.html</guid> 
<pubDate>Wed, 10 Oct 2007 15:28:09 GMT</pubDate> 
<link>http://scrolls.combats.com/community/~developers/74715.html</link><author>developers : Alex Nomad</author>
<title>Начинающим клановым программистам</title>
<description>&lt;a href=&quot;http://scrolls.ru/~Alex&#37;20Nomad/74713.html&quot; target=&quot;_blank&quot;&gt;Начинающим клановым программистам. Часть III.&lt;/a&gt;&lt;br&gt;&lt;br&gt;Немного о безопасности.</description> 
</item>
<item>
<guid isPermaLink="true">http://scrolls.combats.com/community/~developers/74083.html</guid> 
<pubDate>Tue, 09 Oct 2007 13:35:40 GMT</pubDate> 
<link>http://scrolls.combats.com/community/~developers/74083.html</link><author>developers : Alex Nomad</author>
<title>Карты торговца и запрет shop.pl?contents=...</title>
<description>С недавних пор перестала работать ссылка http://capitalcity.combats.ru/shop.pl?contents=.... Эта ссылка используется в Картах Торговца для загрузки информации о наличии товаров в магазинах. В настоящий момент парктически все карты торговца БК показывают устаревшие данные или не работают совсем. При этом ссылка загрузки информации из комиссионок работают по прежнему нормально.&lt;br&gt;&lt;br&gt;Если данный запрет установлен навсегда, то будет совсем плохо. Придется ботов рассылать по магазинам.&lt;br&gt;Меня посетила ужасная мысль, если причина запрета вызвана появлением второй части статьи &quot;Начинающим клановым программистам&quot;, то получается, что как мужщина я должен покончить жизнь выстрелом пистолета в висок.&lt;br&gt;А умирать совсем не хочется.&lt;br&gt;&lt;br&gt;П.С. Сделана копия поста в &lt;a href=&quot;http://scrolls.ru/~Alex&#37;20Nomad/74084.html&quot; target=&quot;_blank&quot;&gt;личном дневнике&lt;/a&gt;.</description> 
</item></channel>
</rss>