эта статья серьезно устарела и будет обновлена в ближайшее времясильные>шрифт><п />и
Это реализация посыльный MSN протокола в Delphi это не полный и для того, чтобы ее построить вам понадобятся WSocket пакет, то большинство из того, что представлено здесь, является частью Спецификация (еще не хватало, чтобы даже урезанный клон МСН мессенджер). Работы, которые вы видите здесь, имеет свои задачи (большинство из-за того, что я просто новичок в программировании сокетов), данная статья основана на работах статьи venkydude MSN и старой версии KMerlin (с открытым исходным кодом MSN мессенджера клон для Linux). В этой статье я пишу о обмен мгновенными сообщениями (первый о Yahoo протоколу, который я не смог завершить из-за нехватки времени (много работы)) я планирую обновлять эту статью, как только возможное р><р>< & & & & & & & & & & & & & & & & -код & & & & & & & & & & & & & & & & & & & & >
<код><шрифта лицо="курьер Нью" Размер="3"><цвет шрифта="#число 0000ff"><я>{глобальный задач: ввести локальные задачи, очистки, продления}
ВЯ>шрифт>иустройство в MSNMessenger
<б>интерфейс
использование функции
б>WSocket, алгоритм MD5, классы, Модуля приведет к
<б>Тип
и б>TUserState = (
В usOnline, <цвет шрифта="#число 0000ff"><я>// Вы не Интернет
я>шрифт>usBusy, <цвет шрифта="#число 0000ff"><я>// на самом деле занят и
я>шрифт>usBRB, <цвет шрифта="#число 0000ff"><я>// вернусь и
я>шрифт>usAway, <цвет шрифта="#число 0000ff"><я>// выезде в
я>шрифт>usOnPhone, <цвет шрифта="#число 0000ff"><я>//о
телефон я>шрифт>usLunch, <цвет шрифта="#число 0000ff"><я>//обед с
я>шрифт>usHidden, <цвет шрифта="#число 0000ff"><я>//скрытой и
я>шрифт>usOffline <цвет шрифта="#число 0000ff"><я>//автономных и
я>шрифт>)
В TMSNMessenger = <Б>классб>(TComponent)
<б>Частная
и б>FConnected: логическое
В FUserName: <б>строкаб>
FPassword: <б>строкаб>
FFriendlyUserName: <б>строкаб>
пороть: TStrings
В FFriendlyNameChange: TNotifyEvent
В FState: TUserState
<б>функции в GetHost: <б>строкаб>
<б>процедура на SetHost(<б>константный б>значение: <б>строка в)
<б>функции , и GetPort: и строкаб>
<б>процедура на SetPort(<б>константный б>значение: <б>строка в)
<б>процедура б>SetUserName(<б>константный б>значение: <б>строка в)
<б>процедура , и задание пароля(<б>константный б>значение: и строка в)
<б>функции в GetFriendlyUserName: <б>строкаб>
<б>процедура на SetFriendlyUserName(<б>константный б>значение: <б>строка в)
<б>процедура : при выполнении функция setstate(<б>константный б>значение: TUserState)
<б>защищенные и
б>FSocket: TWSocket
В FTrialID: число
<б>процедура в SendVER
<б>процедура на ReceiveSYN
<б>процедура на SocketWrite(<б>константный б>строка: <б>строкаб>)
<б>процедура , и как logwrite(<б>константный б>данные: <б>строка в)
<б>процедура на ProcessCommand(<б>константный б>команда: <б>строка в)
<б>процедура в SocketDisconnect(Отправитель: TObject ошибка: слово)
<б>процедура в SocketDataAvailable(Отправитель: TObject ошибка: слово)
<б>процедура на SocketConnect(Отправитель: TObject ошибка: слово)
<б>процедура на TriggerFriendlyNameChange <б>динамичностьб>
<б>общие
конструктор б>создать(AOwner: TComponent) <б>переопределитьб>
<б>деструктор б>уничтожить <б>переопределитьб>
<б>процедура б>логин
<б>процедура на выходе
<б>опубликовано на
свойства на хост: <б>строка б>GetHost <б>пишут б>SetHost
<б>недвижимость в Порт <б>строка , и GetPort <б>пишут б>SetPort
<б>собственность б>Имя пользователя: <б>строка б>FUserName <б>пишут б>SetUserName
<б>собственность б>пароль: <б>строка б>FPassword <б>пишут , и задание пароля
<б>собственность б>FriendlyUserName: <б>строка б>GetFriendlyUserName <б>пишут б>SetFriendlyUserName
<б>недвижимость в связи: логическое и ознакомиться на FConnected
<б>недвижимость в лог: TStrings и ознакомиться , и пороть <б>пишут б>выпороть
<б>собственность б>FriendlyNameChange: TNotifyEvent и ознакомиться на FFriendlyNameChange <б>пишут б>FFriendlyNameChange
<б>собственность б>Статус: TUserState и ознакомиться в FState <б>пишут : при выполнении функция setstate
<б>конецб>
<б>реализация
использование б>окна
<б>константный б>RealState: <б>массивб>[TUserState] <б>строки б>=
и (<цвет шрифта="#800000">'ЧГ %д НЛН'шрифт>, <цвет шрифта="#800000">'ЧГ %д школа бум'шрифт>, <цвет шрифта="#800000">'ЧГ %д БРБ'шрифт>, <цвет шрифта="#800000">'ЧГ %д авиалиниях'шрифт>, <цвет шрифта="#800000">'ЧГ %д ПТС'шрифт>, <цвет шрифта="#800000">'ЧГ %д луньшрифт>,
<цвет шрифта="#800000">'ЧГ %д СЗР'шрифт>, <цвет шрифта="#800000">'ЧГ %д НФО' шрифт>)
<б>Тип
и б>Кодировка = В наборе б>чар
<б>функции в UTF8ToAnsi(х: <б>строкаб>): ansistring
<цвет шрифта="#число 0000ff"><я>{ функция, которая получает в UTF8 строку и преобразует в
В ANSI строку }в
я>шрифт><б>вар
В мне: целое число
В В1, В2: байт
<б>начинается
б>результат := х
я := <цвет шрифта="#800080">1шрифт>
<Б>А мне <= Длина(результат) <б>начинаются
если б>(орд(результат[я]) и б><цвет шрифта="#800080">$80шрифт>) <> <цвет шрифта="#800080">0 шрифт><б>потом начинается
б>Б1 := ОГА(результат[я])
В Б2 := ОГА(результат[я <цвет шрифта="#800080">1шрифт>])
при б>(В1 и б><цвет шрифта="#800080">$Ф0шрифт>) <> <цвет шрифта="#800080">$Ц0 шрифт><б>то есть
б>результат[я] := <цвет шрифта="#800000">#128
В шрифт><б>еще начинается
б>результат[я] := ЧР((В1 <б>ЗЫ б><цвет шрифта="#800080">6шрифт>) или б>(В2 и б><цвет шрифта="#800080">$3фшрифт>))
и удалить(результат, я <цвет шрифта="#800080">1шрифт>, <цвет шрифта="#800080">1шрифт>)
<б>конецб>
<б>конецб>
Инк(я)
<б>конецб>
<б>конецб>
<б>функции в AnsiToUtf8(х: ansistring): и строкаб>
<цвет шрифта="#число 0000ff"><я>{ функция, которая принимает строку и преобразует в ANSI
для строк UTF8 }в
я>шрифт><б>вар
В мне: целое число
В В1, В2: байт
<б>начинается
б>результат := х
для мне := Длина(результат) <б>до б><цвет шрифта="#800080">1 шрифт><б>делать
если в результате[я] >= <цвет шрифта="#800000">#127 шрифт><б>затем начинается
б>Б1 := <цвет шрифта="#800080">$Ц0 шрифт>или б>(орд(результат[я]) <б>ГТК б><цвет шрифта="#800080">6шрифт>)
В Б2 := <цвет шрифта="#800080">$80 шрифт>или б>(ОГА(результат[я]) и б><цвет шрифта="#800080">$3фшрифт>)
В результате[я] := ЧР(В1)
и вставить(ЧР(В2), результат, я <цвет шрифта="#800080">1шрифт>)
<б>конецб>
<б>конецб>
<б>функции , и ExtractWord(Н:целое число S: истрокаб> WordDelims:Кодировка): истрокаб>
<б>Вар
В мне,Дж:слова
В подсчет:число
и Слен:Целое число
<б>начинается
б>граф := <цвет шрифта="#800080">0шрифт>
я := <цвет шрифта="#800080">1шрифт>
В результате := <цвет шрифта="#800000">"шрифт>
и Слен := Длина(с)
<Б>А мне <= Слен <б>делать начинается
б><цвет шрифта="#число 0000ff"><я>{preskoc oddelovace}
В Я>шрифт><Б>А Б>(Я <= Слен) <б>и (С[Я] В Б>WordDelims) <б>делать б>Инк(я) в
<цвет шрифта="#число 0000ff"><я>{нени-ли на konci retezce, буде nalezen zacatek слова}
В Я>шрифт>при мне <= Слен и тогда б>Инк(счет)
и Х := У меня есть
<цвет шрифта="#число 0000ff"><я>{а зде йе конец слова}
В Я>шрифт><Б>А Б>(К <= Слен) и неб>(s[Дж] В на WordDelims) и у б>Инк(Дж)
<цвет шрифта="#число 0000ff"><я>{йе-ли Тото н-т е слово, vloz хо на выступ}
В Я>шрифт>при б>Кол-во = Н <Б>затем начинается
б>результат := экземпляр(ы,я,Ю-Я)
на выходе
<б>конецб>
я := Дж
<б>конецб> <цвет шрифта="#число 0000ff"><я>{А} и
я>шрифт>в концеб>
<б>функции на WordAt(<б>константный текст : и строка на установки : целое число) : текст строкаб>
<б>начинается
б>результат := ExtractWord(положение, текст, [<цвет шрифта="#800000">' 'шрифт>])
<б>конецб>
<цвет шрифта="#число 0000ff"><я>{ TMSNMessenger }в
я>шрифт><б>конструктор б>TMSNMessenger.Создать(AOwner: TComponent)
<б>начинается
наследство б>создать(AOwner)
В FSocket := TWSocket.Создать(Самовыдвижение)
В FSocket.Значение addr := <цвет шрифта="#800000">'messenger.hotmail.com'шрифт>
В FSocket.Порт := <цвет шрифта="#800000">'1863'шрифт>
В FSocket.Прото:= <цвет шрифта="#800000">'ПТС'шрифт>
В FSocket.OnSessionConnected := SocketConnect
В FSocket.OnSessionClosed := SocketDisconnect
В FSocket.OnDataAvailable := SocketDataAvailable
В FConnected := ложь
<б>конецб>
<б>деструктор б>TMSNMessenger.Уничтожить
<б>начинается
б>FSocket.Бесплатные
FSocket := <б>Нилб>
<б>наследство б>уничтожить
<б>конецб>
<б>функции в TMSNMessenger.GetFriendlyUserName: <б>строкаб>
<б>начать
если не б>FConnected <б>то есть
б>результат := FFriendlyUserName
<б>конецб>
<б>функции в TMSNMessenger.GetHost: <б>строкаб>
<б>начинается
б>результат := FSocket.АДР
<б>конецб>
<б>функции б>TMSNMessenger.GetPort: <б>строкаб>
<б>начинается
б>результат := FSocket.Порт
<б>конецб>
<б>процедура б>TMSNMessenger.Логин
<б>начинается
б>FSocket.Подключения
<б>конецб>
<б>процедура б>TMSNMessenger.Выход
<б>начинается
конецб>
<б>процедура в TMSNMessenger.Как logwrite(<б>константный б>данные: <б>строка в)
<б>начать
если , и назначена( пороть ) <б>то есть
б>выпороть.Добавить(данные)
<б>конецб>
<цвет шрифта="#число 0000ff"><я>{Processcommand здесь сродни процедуре windowproc
как мы обрабатываем все виды информации, переданных с сервера
как сейчас это IFFull (полный ли это) возможно, если бы я
есть немного свободного времени станет в этом случае
В ТОДО: Очистить этот порядок испортить и
todo: добавьте больше команд}
ВЯ>шрифт>ипроцедура в TMSNMessenger.ProcessCommand
<б>вар
б>Тмп: <б>строкаб>
хэш: <б>строкаб>
<б>начинается
б>Тмп := WordAt(команда, <цвет шрифта="#800080">1шрифт>) в
при б>Тмп = <цвет шрифта="#800000">'Сильвер' шрифт><б>то есть
б>SocketWrite(<цвет шрифта="#800000">'инф %д'шрифт>) и
при б>Тмп = <цвет шрифта="#800000">'инф' /шрифт><б>то есть
б>SocketWrite(<цвет шрифта="#800000">'УСР %д с MD5 я 'шрифт> FUserName)
при б>Тмп = <цвет шрифта="#800000">'ЕГР' шрифт>, и тогда
и начинается
если б>WordAt(команда, <цвет шрифта="#800080">4шрифт>) = <цвет шрифта="#800000"> " с " шрифт>, и тогда
и начинается
б>хэш := WordAt(команда, <цвет шрифта="#800080">5шрифт>)
и удалить(хэш, пос(<цвет шрифта="#800000">#13#10шрифт>, Хэш), длины(хэш))
хэш := StrMD5(хэш пароля)
В SocketWrite(<цвет шрифта="#800000">'УСР %д MD5 В С' шрифт> строчные(хэш))
<б>конец еще
и начинается
б>FFriendlyUserName := WordAt(команда, <цвет шрифта="#800080">5шрифт>)
В SocketWrite(<цвет шрифта="#800000">'Син %д 1'шрифт>)
В ReceiveSYN
<б>конецб>
<б>конецб>
<цвет шрифта="#число 0000ff"><я>{когда появляется xfr, и Вы не подключены
к MSN сервера это означает перенаправление на другой сервер}в
я>шрифт>при б>(ТМП = <цвет шрифта="#800000">'деятельность компании xfr'шрифт>) и не б>подключено <б>затем
и начинается
б>ТМП := WordAt(команда, <цвет шрифта="#800080">4шрифт>)
В FSocket.Рядом с
удалить(ТСП, пос(<цвет шрифта="#800000">':'шрифт>, Тмп), Длина(Тмп))
В FSocket.Адрес := Тмп
В ТМП := WordAt(команда, <цвет шрифта="#800080">4шрифт>)
и удалить(Тмп <цвет шрифта="#800080">1шрифт>, пос.(<цвет шрифта="#800000">':'шрифт>, Тмп))
В FSocket.Порт := Тмп
В FSocket.Подключения
на выходе
<б>конецб>
<цвет шрифта="#число 0000ff"><я>{переименовать имя} и
я>шрифт>при б>(ТМП = <цвет шрифта="#800000">'РЭА'шрифт>) и тут
и начинается
б>FFriendlyUserName := WordAt(команда, <цвет шрифта="#800080">5шрифт>)
В FFriendlyUserName := StringReplace(FFriendlyUserName, <цвет шрифта="#800000">' 'шрифта>, <цвет шрифта="#800000">' 'шрифт>, [rfReplaceall])
В TriggerFriendlyNameChange
<б>конецб>
<цвет шрифта="#число 0000ff"><я>{из команды до сервера
что разъединяет нас, если это потому, что мы вошли в другую машину
мы получили сообщение из другой (другая машина)
как сделать запись какого-либо события или что-то для получения этого уведомления}в
я>шрифт>при б>(ТМП = <цвет шрифта="#800000">выходшрифт>) и тут
и начинается
если в пос(<цвет шрифта="#800000">'дру'шрифт>, команда) > <цвет шрифта="#800080">1 шрифт><б>то есть
б>как logwrite(<цвет шрифта="#800000">'войти в другой компьютер отключение'шрифт>)
<б>конецб>
<б>конецб>
<цвет шрифта="#число 0000ff"><я>{Син-это, без сомнения, самый информацияполный посыльный MSN команду
и Син сообщает нам:
В наличии по электронной почте
и друг
списка черный список
в обратный список (люди, которые вас в свои списки)
все номера телефонов (Домашний, мобильный и т. д.)
В MSN мессенджера параметры
и т. д.
однако, это приходит с ценой, поскольку существует так много информации
WSocket не может получить все данные правильно (качество не блокирующих сокетов)
таким образом для того чтобы сделать это мы будем мерзнуть этой теме в течение 5 секунд
вы(то есть ваши формы не будет получать никаких Сообщений
и, кажется, не отвечает на некоторое время), я
вы знаете, там должен быть лучший способ, если кто-то знает, напишите мне.
и сделать анализ полученных данных.
на будущее : найти способ, который не придется мерзнуть нить есть
}
ВЯ>шрифт>ипроцедура на TMSNMessenger.ReceiveSYN
<б>вар
б>Тмп: <б>строкаб>
<б>начинается
б>FSocket.OnDataAvailable := <б>Нилб>
сон(<цвет шрифта="#800080">5000шрифт>)
В Тмп := FSocket.ReceiveStr
В FSocket.OnDataAvailable := SocketDataAvailable
В Тмп := UTF8ToAnsi(Тмп)
и как logwrite(<цвет шрифта="#800000">'принято :' шрифт> Тмп)
В SocketWrite(<цвет шрифта="#800000">'ЧГ %д НЛН'шрифт>)
<б>конецб>
<б>процедура на TMSNMessenger.SendVER
<б>начинается
б>SocketWrite(<цвет шрифта="#800000">'Сильвер %д CVR0 MSNP5 MSNP6 MSNP7'шрифт>)
<б>конецб>
<б>процедура на TMSNMessenger.SetFriendlyUserName(<б>константный б>значение: <б>строка в)
<б>вар
б>тмп: <б>строкаб>
<б>начать
если б>FConnected <б>и (FUserName <> значение) и тут
и начинается
б>тмп := StringReplace(значения <цвет шрифта="#800000">' 'шрифта>, <цвет шрифта="#800000">' 'шрифт>, [rfReplaceAll])
В тмп := AnsiToUtf8(Тмп)
В SocketWrite(<цвет шрифта="#800000">'РИ %д' шрифт> FUsername <цвет шрифта="#800000">' 'шрифт> тмп)
<б>конецб>
<б>конецб>
<б>процедура в TMSNMessenger.SetHost(<б>константный б>значение: <б>строка в)
<б>начать
если не б>подключено <б>потом
если б>FSocket.Адрес <> значение <б>то есть
б>FSocket.Адрес := значение
<б>конецб>
<б>процедура в TMSNMessenger.Задание пароля(<б>константный б>значение: <б>строка в)
<б>начать
если не б>подключено <б>затем
если б>(FPassword <> значение) <б>то есть
б>FPassword := Значение
<б>конецб>
<б>процедура в TMSNMessenger.SetPort(<б>константный б>значение: <б>строка в)
<б>начать
если не б>подключено <б>потом
если б>FSocket.Порт <> значение <б>то есть
б>FSocket.Порт := значение
<б>конецб>
<б>процедура в TMSNMessenger.Выполнении функция setstate(<б>константный б>значение: TUserState)
<б>начать
если б>FConnected <б>потом
если б>(FState <> значение) <б>то есть
б>SocketWrite( RealState[значение] )
<б>конецб>
<б>процедура на TMSNMessenger.SetUserName(<б>константный б>значение: <б>строка в)
<б>начать
если не б>FConnected , и тогда
если б>FUsername <> значение <б>то есть
б>FUserName := значение
<б>конецб>
<б>процедура на TMSNMessenger.SocketConnect(Отправитель: TObject ошибка: слово)
<б>начинается
б>FTrialID := <цвет шрифта="#800080">1шрифт>
В SendVER
<б>конецб>
<б>процедура в TMSNMessenger.SocketDataAvailable(Отправитель: TObject ошибка: слово)
<б>вар
б>Тмп: <б>строкаб>
<б>начинается
б>Тмп := FSocket.ReceiveStr
В Тмп := UTF8ToAnsi(Тмп)
и как logwrite(<цвет шрифта="#800000">'принято :' шрифт> Тмп)
В ProcessCommand(Тмп)
<б>конецб>
<б>процедура на TMSNMessenger.SocketDisconnect(Отправитель: TObject ошибка: слово)
<б>начинается
б>FConnected := ложь
и как logwrite(<цвет шрифта="#800000">'отключен'шрифт>)
<б>конецб>
<б>процедура в TMSNMessenger.SocketWrite(<б>константный б>строка: <б>строка в)
<б>начинается
б>FSocket.SendStr(Формат(строка, [FTrialID]) <цвет шрифта="#800000">#13шрифт> <цвет шрифта="#800000">#10шрифт>)
и как logwrite(<цвет шрифта="#800000">'Отправлено :' шрифт> Формат(строка, [FTrialID]))
В Инк(FTrialID)
<б>конецб>
<б>процедура б>TMSNMessenger.TriggerFriendlyNameChange
<б>начать
если , и назначена(FFriendlyNameChange) <б>то есть
б>FFriendlyNameChange(Самовыдвижение)
<б>конецб>
<б>конецб>.шрифт>код>< & & & & & & & & & & & & & & & & -/код & & & & & & & & & & & & & & & & & & & -> пример был бы: AMSN := TMSNMessenger.Создания(самостоятельного) // AMSN является переменной TMSNMessenger Тип AMSN.Имя пользователя := " // указывает имя пользователя, который всегда должен быть в форме *@hotmail.com AMSN.Пароль := " //это указывает на AMSN пароль.Отчет := Наименованием "Memo1".Линии // журнал указывает пункт назначения, чтобы сбросить полученные и отправленные данные, я использую его для поиска информации, протокола и прочее, но это не обязательно использовать его AMSN.Логин // процедура, которая означает, что мы должны начать процесс входа в систему