Что нового

Помогите разобраться с работой с ICQ DLL

ynbIpb

Скриптер
Сообщения
399
Репутация
110
Re: ICQ DLL

хм... Хитрость какаята. Ну ладно значит проблема в моей системе.
Тут возникла другая трабла:
На сколько известно сообщение отправляемое ботом не может превышать 2500 байт приблизительно.
Решил я его резать если оно длиннее, но вот проблема, я юзаю UTF-8, а там 1 русская буква занимает 2 байта и при нарезке бывает, что разрезается 1 буква на части. Из-за этого целый кусок превращается в кракозябры, так как сбит порядок байт. Необходимо как-то идентифицировать конец буквы и только тогда отрезать текст. Есть мысли?
Код:
#include <Encoding.au3>
Func _sendanswer($answer, $recipient); функция отправки ответ хозяину бота: 1 парметр - текст, 2 - UIN получателя
$sUTF8_answer = _Encoding_StringToUTF8($answer); преобразуем в UTF-8

$len_msg = StringLen ($sUTF8_answer); определяем длинну строки
If $len_msg >= 2500 Then ; если строка длиннее 2500 символов, то отсылаем по частям.
	$i = 1
	While 1 ; крутим цикл пока не кончится текст
		$cutting = StringMid($sUTF8_answer, $i, 2500)
		If $cutting = "" Then ExitLoop
		ICQSendMsg($recipient, $cutting)
		sleep (2000); пауза 2 сек, чтоб не забанили за массовую рассылку
		$i += 2500
	WEnd
Else ; иначе отправляем в обычном режиме
	ICQSendMsg($recipient, $sUTF8_answer)
EndIf
EndFunc

StringLen в случае с UTF-8 возвращает не количество букв, а количество байт.
 

Guezt

Продвинутый
Сообщения
335
Репутация
82
Re: ICQ DLL

ynbIpb

Хм, попробуй до 2496 размер и отправку по байтам а не по буквам

ynbIpb [?]
StringLen в случае с UTF-8 возвращает не количество букв, а количество байт.





Добавлено:
Сообщение автоматически объединено:

Или сначала "реж" текст, а потом "куски" преобразуй в UTF8
попробуй так:
Код:
#include <Encoding.au3>
Func _sendanswer($answer, $recipient); функция отправки ответ хозяину бота: 1 парметр - текст, 2 - UIN получателя
;$sUTF8_answer = _Encoding_StringToUTF8($answer); преобразуем в UTF-8
;$len_msg = StringLen ($sUTF8_answer); определяем длинну строки
$len_msg = StringLen ($answer); определяем длинну строки
If $len_msg >= 2496 Then ; если строка длиннее ~2500 символов, то отсылаем по частям.
    $i = 1
    While 1 ; крутим цикл пока не кончится текст
        $cutting = StringMid($answer, $i, 2496)
        If $cutting = "" Then ExitLoop
        $sUTF8_answer = _Encoding_StringToUTF8($cutting); преобразуем в UTF-8
        ICQSendMsg($recipient,$sUTF8_answer)
        sleep (2000); пауза 2 сек, чтоб не забанили за массовую рассылку
        $i += 2496
    WEnd
Else ; иначе отправляем в обычном режиме
    $sUTF8_answer = _Encoding_StringToUTF8($answer); преобразуем в UTF-8
    ICQSendMsg($recipient, $sUTF8_answer)
EndIf
EndFunc
 

ynbIpb

Скриптер
Сообщения
399
Репутация
110
Re: ICQ DLL

Дело в том, что текст смешаннный (англ и рус), а в англ. буквах 1 байт используется, в русских 2 байта. По этому разбивая по количеству байт невозможно угадать где конец буквы будет.
Если же резать текст заранее, то невозможно угадать сколько будет байт после преобразования, так как русские символы становятся 2 байта.
Вообще тупик.
 

Guezt

Продвинутый
Сообщения
335
Репутация
82
Re: ICQ DLL

ynbIpb
Ну попробуй сделать проверку приобразования и если меньше 2500 то выслать сообщение если больше то "откусывать" по одному символу - преобразовывать и прибовлять к сообщению как будет нужной длины высылать и продолжать остаток приобразовывать, в общем пока не кончатся буквы попробуй в общем так я сам проверить не могу:
Код:
#include <Encoding.au3>
Func _sendanswer($answer, $recipient); функция отправки ответ хозяину бота: 1 парметр - текст, 2 - UIN получателя
$sUTF8_answer = _Encoding_StringToUTF8($answer); преобразуем в UTF-8
$len_msg = StringLen ($sUTF8_answer); определяем длинну строки
If $len_msg > 2496 Then ; если строка длиннее ~2500 символов, то отсылаем по частям.
    $i = 1
   $msg = ""
   For $i = 1 To StringLen($answer) ; от одного до количества букв-символов
      $cutting = StringMid($answer, $i) ; начинаем резать по одной букве|символу
        $sUTF8_answer = _Encoding_StringToUTF8($cutting); преобразуем в UTF-8
      IF StringLen ($sUTF8_answer) < 2049 Then ; если меньше 2500 то...
      $msg = $sUTF8_answer ; добавляем к сообщению
      Else ; если больше то
        $i = $i -1 ; откатимся на один символ назад т.к. пойдет в другое сообщение уже. незнаю верно ли тут сделать $i -= $i не силен в подобных операндах :)
        ICQSendMsg($recipient,$msg) ; отсылаем то что есть и
      $msg = "" ; и очищаем сообщение для отправки
      sleep (2000); пауза 2 сек, чтоб не забанили за массовую рассылку
       EndIf
      $i+=$i
   Next
   $i = 1
   $msg =""
Else ; иначе отправляем в обычном режиме
   ICQSendMsg($recipient, $sUTF8_answer)
EndIf
EndFunc
 

ynbIpb

Скриптер
Сообщения
399
Репутация
110
Re: ICQ DLL

Код:
$ICQmessageBin = StringToBinary("строка1Строка2Строка3Строка4Строка5Строка6", 4); преобразуем в UTF-8
$ICQmessageUtf = BinaryToString ($ICQmessageBin , 1)
$lenn = StringLen ($ICQmessageUtf)
$lenn_b = BinaryLen ($ICQmessageBin)
MsgBox (0, "", "Длинна строки в символах: "&$lenn&@crlf&"Длинна строки в байтах: "&$lenn_b)

Что длинна в буква, что длинна в байтах = одинаково
Думаю это можно назвать багом?
 

Guezt

Продвинутый
Сообщения
335
Репутация
82
Re: ICQ DLL

ynbIpb [url_ex=javascript:qq.OpenLink('[url=http://autoit-script.ru/index.php?topic=788.msg8724#msg8724%27]Re: ICQ DLL)][?][/url_ex]
Что длинна в буква, что длинна в байтах = одинаково
Нет в основном по 1 байту длина, но спецсимволы и символы могут быть до 6 байт юникод 2 байта ISO UTF8 то что я предложил работает ?
 

ynbIpb

Скриптер
Сообщения
399
Репутация
110
Re: ICQ DLL

с первого раза не совсем понял принцип, а теперь всё понятно. преобразовывается в UTF-8 по 1 букве. Отличная идея, работать будет. Спасибо.
 

timsky

Осваивающий
Сообщения
93
Репутация
28
Re: ICQ DLL

Не работает у меня на AutoIt 3.3.4.0 (Win 7 х64 и ХР х86 SP3 на реальной и виртуальной машинах) :(

Скачал архив из этого сообщения: http://autoit-script.ru/index.php?topic=788.msg5576#msg5576
Прописал рабочие UIN/pass в конфиг.
master - номер, на который будут слаться мессаги?

Запускаю client.au3 ломится на асечный сервак, пишет System: Status - 0 и не работает.

Также попробовал (и поправил) test.au3 - Not connected :(


Скачал подправленый Client.au3: http://autoit-script.ru/index.php?topic=788.msg5591#msg5591
То же самое: System: could not connect!

Это у меня одного так? Файрвол везде отключал, выгружал...


Разобрался!
У меня $aRet[0] возвращает 4294967295 при удачном подключении и UDF думает, что коннекта не было. Поправил - и все заработало. Т.е. строку 37 сделал такой:
Код:
if $aRet[0] = $ICQ_CONNECT_STATUS_OK Or $aRet[0] = 4294967295 Then


Попробовал с UZ/US айпишников, невидимки и видимые номера, 7-ки, 9-ки, поюзаные и нет - все время выдает это число 4294967295.
У кого-нибудь еще возвращает подобное?
 

SECTOR

Продвинутый
Сообщения
399
Репутация
59
Re: ICQ DLL

У кого-нибудь еще возвращает подобное?

На днях начал писать ICQ бота, и понял, что у меня ICQConnect возвращает 0 в любом случае :(

timsky, у меня так же!
Зря писал...
 

ynbIpb

Скриптер
Сообщения
399
Репутация
110
Re: ICQ DLL

Давно забил на ICQ бота, но вот решил вернуться к нему. Отдельное спасибо timsky, за выявление баги в if $aRet[0] = $ICQ_CONNECT_STATUS_OK.
Заметил, что вроде как не срабатывает функция ICQClose(), которая должны дисконектить бота. Я её вызываю при завершении работы скрипта (OnAutoItExitRegister), После завершения Уин продолжает висеть онлайн, и потом отваливается по таймауту. У кого как?
Код:
Func ICQClose()
	DllCall($ICQMOD_DLL, "dword", "ICQClose", "ptr", DllStructGetPtr($stICQ_CLIENT))
EndFunc
 

Heler

Знающий
Сообщения
70
Репутация
11
Re: ICQ DLL

ynbIpb сказал(а):
Давно забил на ICQ бота, но вот решил вернуться к нему. Отдельное спасибо timsky, за выявление баги в if $aRet[0] = $ICQ_CONNECT_STATUS_OK.
Заметил, что вроде как не срабатывает функция ICQClose(), которая должны дисконектить бота. Я её вызываю при завершении работы скрипта (OnAutoItExitRegister), После завершения Уин продолжает висеть онлайн, и потом отваливается по таймауту. У кого как?
Код:
Func ICQClose()
	DllCall($ICQMOD_DLL, "dword", "ICQClose", "ptr", DllStructGetPtr($stICQ_CLIENT))
EndFunc
У меня все нормально. После использования функции ICQClose контакт моментально пропадает из списка онлайн юзеров. Возможно это особенность вашего ICQ клиента? Я использую QIP 2005 Build 8095.(AutoIT 3.3.4.0)
 

Nik_rus

Python The Snake.
Сообщения
214
Репутация
62
Re: ICQ DLL

У меня тоже ICQClose срабатывает.
 

HORRIBLE

Знающий
Сообщения
22
Репутация
10
Re: ICQ DLL

Nik_rus сказал(а):
(Пишу с телефона, сильно не пинать)
все очень просто:
Код:
$status = ICQConnect("login.icq.com:5190","UIN","password") ; подключаемся...
MsgBox(0,"Info","Status: " & $status)
ICQAskAuth("UIN","Auth :)") ; просим контакт нас афторизировать
Sleep(10000)
ICQAuth("UIN") ; и дополнительно сами его афторайзим
ICQSendMsg("UIN","Message") ; собсно месаг
$online = 1
while $online = 1
$msg = ICQReadMsg() ; читаем входящие сообщения
if $msg<>0 Then
ICQSendMsg($msg[0],"[ " & $msg[0] & " ]: " & $msg[1]) ; шлем присланный месаг
$online = 0
EndIf
ICQClose() ; закрываем...

На пример есть:
uin1 и uin2 тогда код должен выглядеть так:
Код:
$status = ICQConnect("login.icq.com:5190","UIN1","password") ; подключаемся...
MsgBox(0,"Info","Status: " & $status)
ICQAskAuth("UIN1","Auth") ; просим контакт нас афторизировать
Sleep(10000)
ICQAuth("UIN1") ; и дополнительно сами его афторайзим
ICQSendMsg("UIN2","Message") ; собсно месаг
$online = 1
while $online = 1
$msg = ICQReadMsg() ; читаем входящие сообщения
if $msg<>0 Then
ICQSendMsg($msg[0],"[ " & $msg[0] & " ]: " & $msg[1]) ; шлем присланный месаг
$online = 0
EndIf
ICQClose() ; закрываем...


А зачем строчки :
ICQAskAuth("UIN","Auth :smile:") ; просим контакт нас афторизировать
ICQAuth("UIN") ; и дополнительно сами его афторайзим
 

Nik_rus

Python The Snake.
Сообщения
214
Репутация
62
Дело в том, что (ну, вроде бы так, я точно не помню), что неавторизованные в контакт-листе юзеры не могут послать вам сообщения. Им нужна предварительная авторизация вами.
 

sss

Продвинутый
Сообщения
332
Репутация
96
А можно все это дело пустить через HTTP-прокси?
 

Guezt

Продвинутый
Сообщения
335
Репутация
82
OffTopic:
Sky-WaLkeR
Можно. Пускай. ;D
 

sss

Продвинутый
Сообщения
332
Репутация
96
:smile: А серьезно? Как это можно реализовать? В UDF не нашел флага для HTTP(s)-прокси. Только Socks4\5
 

Nik_rus

Python The Snake.
Сообщения
214
Репутация
62
Нет, к сожалению в самой либе нет поддержки HTTP(s) :(.
Но! Slesh выложил сорцы либы, так что думаю поковыряюсь...
http://slesh.name/uploads/ICQMod_src.zip
 

aleratorio

Осваивающий
Сообщения
85
Репутация
43
Очень долго думал почему у меня самодельный ICQ клиент постоянно переподключается. Нашел ошибку в ICQ.au3

В 32 битном представлении знаковое число 0xFFFFFFFF = -1, а не 4294967295, которое возвращает функция
Код:
DllCall($ICQMOD_DLL, "dword", "ICQConnect", "ptr", DllStructGetPtr($stICQ_CLIENT), "str", $server, "word", $port, "str", $login, "str", $password, "ptr", $stPROXY_INFO)

А так же 0xFFFFFFFE = -2, а не 4294967294 и т.п.

Попробуйте:
Код:
MsgBox(0, '', 0xFFFFFFFF)



Это объясняет и это:
timsky сказал(а):
У меня $aRet[0] возвращает 4294967295 при удачном подключении и UDF думает, что коннекта не было. Поправил - и все заработало. Т.е. строку 37 сделал такой:
Код:
if $aRet[0] = $ICQ_CONNECT_STATUS_OK Or $aRet[0] = 4294967295 Then


Попробовал с UZ/US айпишников, невидимки и видимые номера, 7-ки, 9-ки, поюзаные и нет - все время выдает это число 4294967295.
У кого-нибудь еще возвращает подобное?

Поэтому для верной проверки статуса в ICQ.au3 необходимо заменить значения констант
Код:
Const $ICQ_CONNECT_STATUS_OK = 0xFFFFFFFF
Const $ICQ_CONNECT_STATUS_RECV_ERROR = 0xFFFFFFFE
Const $ICQ_CONNECT_STATUS_SEND_ERROR = 0xFFFFFFFD
Const $ICQ_CONNECT_STATUS_CONNECT_ERROR = 0xFFFFFFFC
Const $ICQ_CONNECT_STATUS_AUTH_ERROR = 0xFFFFFFFB


на

Код:
Const $ICQ_CONNECT_STATUS_OK = 4294967295
Const $ICQ_CONNECT_STATUS_RECV_ERROR = 4294967294
Const $ICQ_CONNECT_STATUS_SEND_ERROR = 4294967293
Const $ICQ_CONNECT_STATUS_CONNECT_ERROR = 4294967292
Const $ICQ_CONNECT_STATUS_AUTH_ERROR = 4294967291
 
Верх