From a9ffe609a8f6af668eebda668efd8e04a8989ef6 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Wed, 26 Dec 2018 23:02:50 +0300 Subject: - icqoscar8 moved to deprecated; - Icq10 is used now as a ICQ protocol; - solutions updated --- bin15/mir_full.sln | 22 +- bin15/mir_icons.sln | 40 +- bin15/miranda32.sln | 66 +- protocols/Icq10/icq10.vcxproj | 2 +- protocols/Icq10/icq_xstatus/CMakeLists.txt | 2 + protocols/Icq10/icq_xstatus/res/ICONS.rc | 132 + protocols/Icq10/icq_xstatus/res/Xstatus34.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus35.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus36.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus38.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus39.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus40.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus41.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus42.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus45.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus46.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus47.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus48.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus49.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus50.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus51.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus52.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus53.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus54.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus56.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus57.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus58.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus59.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus60.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus61.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus62.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus63.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus65.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus66.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus67.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus68.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus69.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus70.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus71.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus72.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus73.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus74.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus75.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus76.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus77.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus78.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus79.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus81.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus82.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus83.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus84.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/Xstatus86.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus01.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus02.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus03.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus04.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus05.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus06.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus07.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus08.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus09.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus10.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus11.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus12.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus13.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus14.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus15.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus16.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus17.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus18.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus19.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus20.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus21.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus22.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus23.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus24.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus25.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus26.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus27.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus28.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus29.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus30.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus31.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus32.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus33.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus37.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus43.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus44.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus55.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus64.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus80.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/res/xstatus85.ico | Bin 0 -> 5430 bytes protocols/Icq10/icq_xstatus/src/resource.h | 103 + protocols/Icq10/icq_xstatus/xStatus_ICQ.vcxproj | 28 + protocols/IcqOscarJ/CMakeLists.txt | 6 - protocols/IcqOscarJ/docs/license.txt | 340 --- protocols/IcqOscarJ/docs/readme.txt | 480 ---- protocols/IcqOscarJ/icq_xstatus/CMakeLists.txt | 2 - protocols/IcqOscarJ/icq_xstatus/res/ICONS.rc | 132 - protocols/IcqOscarJ/icq_xstatus/res/Xstatus34.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus35.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus36.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus38.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus39.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus40.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus41.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus42.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus45.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus46.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus47.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus48.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus49.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus50.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus51.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus52.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus53.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus54.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus56.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus57.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus58.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus59.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus60.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus61.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus62.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus63.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus65.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus66.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus67.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus68.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus69.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus70.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus71.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus72.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus73.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus74.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus75.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus76.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus77.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus78.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus79.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus81.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus82.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus83.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus84.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/Xstatus86.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus01.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus02.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus03.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus04.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus05.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus06.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus07.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus08.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus09.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus10.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus11.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus12.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus13.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus14.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus15.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus16.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus17.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus18.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus19.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus20.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus21.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus22.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus23.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus24.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus25.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus26.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus27.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus28.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus29.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus30.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus31.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus32.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus33.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus37.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus43.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus44.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus55.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus64.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus80.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/res/xstatus85.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/icq_xstatus/src/resource.h | 103 - .../IcqOscarJ/icq_xstatus/xStatus_ICQ.vcxproj | 28 - protocols/IcqOscarJ/icqoscar8.vcxproj | 28 - protocols/IcqOscarJ/icqoscar8.vcxproj.filters | 4 - protocols/IcqOscarJ/proto_icq/CMakeLists.txt | 2 - protocols/IcqOscarJ/proto_icq/Proto_ICQ.vcxproj | 28 - .../IcqOscarJ/proto_icq/Proto_ICQ.vcxproj.filters | 4 - protocols/IcqOscarJ/proto_icq/res/Away.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/proto_icq/res/DND.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/proto_icq/res/FFC.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/proto_icq/res/Invisible.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/proto_icq/res/NA.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/proto_icq/res/Occupied.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/proto_icq/res/Offline.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/proto_icq/res/Online.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/proto_icq/res/Phone.ico | Bin 5430 -> 0 bytes protocols/IcqOscarJ/proto_icq/res/Proto_ICQ.rc | 77 - protocols/IcqOscarJ/proto_icq/src/resource.h | 24 - protocols/IcqOscarJ/res/expandst.ico | Bin 1150 -> 0 bytes protocols/IcqOscarJ/res/resources.rc | 544 ---- protocols/IcqOscarJ/res/version.rc | 9 - protocols/IcqOscarJ/src/askauthentication.cpp | 82 - protocols/IcqOscarJ/src/capabilities.cpp | 247 -- protocols/IcqOscarJ/src/capabilities.h | 43 - protocols/IcqOscarJ/src/chan_01login.cpp | 81 - protocols/IcqOscarJ/src/chan_02data.cpp | 200 -- protocols/IcqOscarJ/src/chan_03error.cpp | 31 - protocols/IcqOscarJ/src/chan_04close.cpp | 279 --- protocols/IcqOscarJ/src/chan_05ping.cpp | 59 - protocols/IcqOscarJ/src/changeinfo.h | 121 - protocols/IcqOscarJ/src/channels.h | 45 - protocols/IcqOscarJ/src/constants.cpp | 131 - protocols/IcqOscarJ/src/cookies.cpp | 254 -- protocols/IcqOscarJ/src/cookies.h | 136 - protocols/IcqOscarJ/src/db.cpp | 153 -- protocols/IcqOscarJ/src/directpackets.cpp | 273 -- protocols/IcqOscarJ/src/dlgproc.cpp | 507 ---- protocols/IcqOscarJ/src/editlist.cpp | 196 -- protocols/IcqOscarJ/src/editstring.cpp | 336 --- protocols/IcqOscarJ/src/fam_01service.cpp | 856 ------- protocols/IcqOscarJ/src/fam_02location.cpp | 257 -- protocols/IcqOscarJ/src/fam_03buddy.cpp | 716 ------ protocols/IcqOscarJ/src/fam_04message.cpp | 2620 -------------------- protocols/IcqOscarJ/src/fam_09bos.cpp | 91 - protocols/IcqOscarJ/src/fam_0alookup.cpp | 118 - protocols/IcqOscarJ/src/fam_0bstatus.cpp | 52 - protocols/IcqOscarJ/src/fam_13servclist.cpp | 1720 ------------- protocols/IcqOscarJ/src/fam_15icqserver.cpp | 1068 -------- protocols/IcqOscarJ/src/fam_17signon.cpp | 161 -- protocols/IcqOscarJ/src/families.h | 73 - protocols/IcqOscarJ/src/globals.h | 59 - protocols/IcqOscarJ/src/guids.h | 76 - protocols/IcqOscarJ/src/i18n.cpp | 499 ---- protocols/IcqOscarJ/src/i18n.h | 61 - protocols/IcqOscarJ/src/icq_advsearch.cpp | 149 -- protocols/IcqOscarJ/src/icq_advsearch.h | 28 - protocols/IcqOscarJ/src/icq_avatar.cpp | 1315 ---------- protocols/IcqOscarJ/src/icq_avatar.h | 118 - protocols/IcqOscarJ/src/icq_clients.cpp | 1007 -------- protocols/IcqOscarJ/src/icq_constants.h | 645 ----- protocols/IcqOscarJ/src/icq_db.cpp | 207 -- protocols/IcqOscarJ/src/icq_direct.cpp | 946 ------- protocols/IcqOscarJ/src/icq_direct.h | 87 - protocols/IcqOscarJ/src/icq_directmsg.cpp | 313 --- protocols/IcqOscarJ/src/icq_fieldnames.cpp | 576 ----- protocols/IcqOscarJ/src/icq_fieldnames.h | 48 - protocols/IcqOscarJ/src/icq_filerequests.cpp | 191 -- protocols/IcqOscarJ/src/icq_filetransfer.cpp | 482 ---- protocols/IcqOscarJ/src/icq_firstrun.cpp | 108 - protocols/IcqOscarJ/src/icq_http.cpp | 198 -- protocols/IcqOscarJ/src/icq_http.h | 44 - protocols/IcqOscarJ/src/icq_infoupdate.cpp | 333 --- protocols/IcqOscarJ/src/icq_menu.cpp | 154 -- protocols/IcqOscarJ/src/icq_opts.cpp | 544 ---- protocols/IcqOscarJ/src/icq_packet.cpp | 895 ------- protocols/IcqOscarJ/src/icq_packet.h | 120 - protocols/IcqOscarJ/src/icq_popups.cpp | 279 --- protocols/IcqOscarJ/src/icq_popups.h | 41 - protocols/IcqOscarJ/src/icq_proto.cpp | 1819 -------------- protocols/IcqOscarJ/src/icq_proto.h | 902 ------- protocols/IcqOscarJ/src/icq_rates.cpp | 445 ---- protocols/IcqOscarJ/src/icq_rates.h | 148 -- protocols/IcqOscarJ/src/icq_server.cpp | 403 --- protocols/IcqOscarJ/src/icq_server.h | 62 - protocols/IcqOscarJ/src/icq_servlist.cpp | 2349 ------------------ protocols/IcqOscarJ/src/icq_servlist.h | 168 -- protocols/IcqOscarJ/src/icq_uploadui.cpp | 873 ------- protocols/IcqOscarJ/src/icq_xstatus.cpp | 1133 --------- protocols/IcqOscarJ/src/icq_xtraz.cpp | 400 --- protocols/IcqOscarJ/src/icqosc_svcs.cpp | 679 ----- protocols/IcqOscarJ/src/icqosc_svcs.h | 35 - protocols/IcqOscarJ/src/init.cpp | 149 -- protocols/IcqOscarJ/src/log.cpp | 150 -- protocols/IcqOscarJ/src/log.h | 34 - protocols/IcqOscarJ/src/loginpassword.cpp | 88 - protocols/IcqOscarJ/src/oscar_filetransfer.cpp | 2116 ---------------- protocols/IcqOscarJ/src/oscar_filetransfer.h | 160 -- protocols/IcqOscarJ/src/resource.h | 168 -- protocols/IcqOscarJ/src/stdafx.cxx | 18 - protocols/IcqOscarJ/src/stdafx.h | 120 - protocols/IcqOscarJ/src/stdpackets.cpp | 1798 -------------- protocols/IcqOscarJ/src/stdpackets.h | 43 - protocols/IcqOscarJ/src/tlv.cpp | 341 --- protocols/IcqOscarJ/src/tlv.h | 76 - protocols/IcqOscarJ/src/upload.cpp | 86 - protocols/IcqOscarJ/src/userinfotab.cpp | 290 --- protocols/IcqOscarJ/src/utilities.cpp | 1695 ------------- protocols/IcqOscarJ/src/utilities.h | 135 - protocols/IcqOscarJ/src/version.h | 13 - 294 files changed, 330 insertions(+), 39201 deletions(-) create mode 100644 protocols/Icq10/icq_xstatus/CMakeLists.txt create mode 100644 protocols/Icq10/icq_xstatus/res/ICONS.rc create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus34.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus35.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus36.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus38.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus39.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus40.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus41.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus42.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus45.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus46.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus47.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus48.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus49.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus50.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus51.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus52.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus53.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus54.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus56.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus57.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus58.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus59.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus60.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus61.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus62.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus63.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus65.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus66.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus67.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus68.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus69.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus70.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus71.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus72.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus73.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus74.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus75.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus76.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus77.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus78.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus79.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus81.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus82.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus83.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus84.ico create mode 100644 protocols/Icq10/icq_xstatus/res/Xstatus86.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus01.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus02.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus03.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus04.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus05.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus06.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus07.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus08.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus09.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus10.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus11.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus12.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus13.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus14.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus15.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus16.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus17.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus18.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus19.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus20.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus21.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus22.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus23.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus24.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus25.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus26.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus27.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus28.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus29.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus30.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus31.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus32.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus33.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus37.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus43.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus44.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus55.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus64.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus80.ico create mode 100644 protocols/Icq10/icq_xstatus/res/xstatus85.ico create mode 100644 protocols/Icq10/icq_xstatus/src/resource.h create mode 100644 protocols/Icq10/icq_xstatus/xStatus_ICQ.vcxproj delete mode 100644 protocols/IcqOscarJ/CMakeLists.txt delete mode 100644 protocols/IcqOscarJ/docs/license.txt delete mode 100644 protocols/IcqOscarJ/docs/readme.txt delete mode 100644 protocols/IcqOscarJ/icq_xstatus/CMakeLists.txt delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/ICONS.rc delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus34.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus35.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus36.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus38.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus39.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus40.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus41.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus42.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus45.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus46.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus47.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus48.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus49.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus50.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus51.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus52.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus53.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus54.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus56.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus57.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus58.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus59.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus60.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus61.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus62.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus63.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus65.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus66.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus67.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus68.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus69.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus70.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus71.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus72.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus73.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus74.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus75.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus76.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus77.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus78.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus79.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus81.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus82.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus83.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus84.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/Xstatus86.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus01.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus02.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus03.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus04.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus05.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus06.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus07.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus08.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus09.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus10.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus11.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus12.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus13.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus14.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus15.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus16.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus17.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus18.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus19.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus20.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus21.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus22.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus23.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus24.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus25.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus26.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus27.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus28.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus29.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus30.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus31.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus32.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus33.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus37.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus43.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus44.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus55.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus64.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus80.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/res/xstatus85.ico delete mode 100644 protocols/IcqOscarJ/icq_xstatus/src/resource.h delete mode 100644 protocols/IcqOscarJ/icq_xstatus/xStatus_ICQ.vcxproj delete mode 100644 protocols/IcqOscarJ/icqoscar8.vcxproj delete mode 100644 protocols/IcqOscarJ/icqoscar8.vcxproj.filters delete mode 100644 protocols/IcqOscarJ/proto_icq/CMakeLists.txt delete mode 100644 protocols/IcqOscarJ/proto_icq/Proto_ICQ.vcxproj delete mode 100644 protocols/IcqOscarJ/proto_icq/Proto_ICQ.vcxproj.filters delete mode 100644 protocols/IcqOscarJ/proto_icq/res/Away.ico delete mode 100644 protocols/IcqOscarJ/proto_icq/res/DND.ico delete mode 100644 protocols/IcqOscarJ/proto_icq/res/FFC.ico delete mode 100644 protocols/IcqOscarJ/proto_icq/res/Invisible.ico delete mode 100644 protocols/IcqOscarJ/proto_icq/res/NA.ico delete mode 100644 protocols/IcqOscarJ/proto_icq/res/Occupied.ico delete mode 100644 protocols/IcqOscarJ/proto_icq/res/Offline.ico delete mode 100644 protocols/IcqOscarJ/proto_icq/res/Online.ico delete mode 100644 protocols/IcqOscarJ/proto_icq/res/Phone.ico delete mode 100644 protocols/IcqOscarJ/proto_icq/res/Proto_ICQ.rc delete mode 100644 protocols/IcqOscarJ/proto_icq/src/resource.h delete mode 100644 protocols/IcqOscarJ/res/expandst.ico delete mode 100644 protocols/IcqOscarJ/res/resources.rc delete mode 100644 protocols/IcqOscarJ/res/version.rc delete mode 100644 protocols/IcqOscarJ/src/askauthentication.cpp delete mode 100644 protocols/IcqOscarJ/src/capabilities.cpp delete mode 100644 protocols/IcqOscarJ/src/capabilities.h delete mode 100644 protocols/IcqOscarJ/src/chan_01login.cpp delete mode 100644 protocols/IcqOscarJ/src/chan_02data.cpp delete mode 100644 protocols/IcqOscarJ/src/chan_03error.cpp delete mode 100644 protocols/IcqOscarJ/src/chan_04close.cpp delete mode 100644 protocols/IcqOscarJ/src/chan_05ping.cpp delete mode 100644 protocols/IcqOscarJ/src/changeinfo.h delete mode 100644 protocols/IcqOscarJ/src/channels.h delete mode 100644 protocols/IcqOscarJ/src/constants.cpp delete mode 100644 protocols/IcqOscarJ/src/cookies.cpp delete mode 100644 protocols/IcqOscarJ/src/cookies.h delete mode 100644 protocols/IcqOscarJ/src/db.cpp delete mode 100644 protocols/IcqOscarJ/src/directpackets.cpp delete mode 100644 protocols/IcqOscarJ/src/dlgproc.cpp delete mode 100644 protocols/IcqOscarJ/src/editlist.cpp delete mode 100644 protocols/IcqOscarJ/src/editstring.cpp delete mode 100644 protocols/IcqOscarJ/src/fam_01service.cpp delete mode 100644 protocols/IcqOscarJ/src/fam_02location.cpp delete mode 100644 protocols/IcqOscarJ/src/fam_03buddy.cpp delete mode 100644 protocols/IcqOscarJ/src/fam_04message.cpp delete mode 100644 protocols/IcqOscarJ/src/fam_09bos.cpp delete mode 100644 protocols/IcqOscarJ/src/fam_0alookup.cpp delete mode 100644 protocols/IcqOscarJ/src/fam_0bstatus.cpp delete mode 100644 protocols/IcqOscarJ/src/fam_13servclist.cpp delete mode 100644 protocols/IcqOscarJ/src/fam_15icqserver.cpp delete mode 100644 protocols/IcqOscarJ/src/fam_17signon.cpp delete mode 100644 protocols/IcqOscarJ/src/families.h delete mode 100644 protocols/IcqOscarJ/src/globals.h delete mode 100644 protocols/IcqOscarJ/src/guids.h delete mode 100644 protocols/IcqOscarJ/src/i18n.cpp delete mode 100644 protocols/IcqOscarJ/src/i18n.h delete mode 100644 protocols/IcqOscarJ/src/icq_advsearch.cpp delete mode 100644 protocols/IcqOscarJ/src/icq_advsearch.h delete mode 100644 protocols/IcqOscarJ/src/icq_avatar.cpp delete mode 100644 protocols/IcqOscarJ/src/icq_avatar.h delete mode 100644 protocols/IcqOscarJ/src/icq_clients.cpp delete mode 100644 protocols/IcqOscarJ/src/icq_constants.h delete mode 100644 protocols/IcqOscarJ/src/icq_db.cpp delete mode 100644 protocols/IcqOscarJ/src/icq_direct.cpp delete mode 100644 protocols/IcqOscarJ/src/icq_direct.h delete mode 100644 protocols/IcqOscarJ/src/icq_directmsg.cpp delete mode 100644 protocols/IcqOscarJ/src/icq_fieldnames.cpp delete mode 100644 protocols/IcqOscarJ/src/icq_fieldnames.h delete mode 100644 protocols/IcqOscarJ/src/icq_filerequests.cpp delete mode 100644 protocols/IcqOscarJ/src/icq_filetransfer.cpp delete mode 100644 protocols/IcqOscarJ/src/icq_firstrun.cpp delete mode 100644 protocols/IcqOscarJ/src/icq_http.cpp delete mode 100644 protocols/IcqOscarJ/src/icq_http.h delete mode 100644 protocols/IcqOscarJ/src/icq_infoupdate.cpp delete mode 100644 protocols/IcqOscarJ/src/icq_menu.cpp delete mode 100644 protocols/IcqOscarJ/src/icq_opts.cpp delete mode 100644 protocols/IcqOscarJ/src/icq_packet.cpp delete mode 100644 protocols/IcqOscarJ/src/icq_packet.h delete mode 100644 protocols/IcqOscarJ/src/icq_popups.cpp delete mode 100644 protocols/IcqOscarJ/src/icq_popups.h delete mode 100644 protocols/IcqOscarJ/src/icq_proto.cpp delete mode 100644 protocols/IcqOscarJ/src/icq_proto.h delete mode 100644 protocols/IcqOscarJ/src/icq_rates.cpp delete mode 100644 protocols/IcqOscarJ/src/icq_rates.h delete mode 100644 protocols/IcqOscarJ/src/icq_server.cpp delete mode 100644 protocols/IcqOscarJ/src/icq_server.h delete mode 100644 protocols/IcqOscarJ/src/icq_servlist.cpp delete mode 100644 protocols/IcqOscarJ/src/icq_servlist.h delete mode 100644 protocols/IcqOscarJ/src/icq_uploadui.cpp delete mode 100644 protocols/IcqOscarJ/src/icq_xstatus.cpp delete mode 100644 protocols/IcqOscarJ/src/icq_xtraz.cpp delete mode 100644 protocols/IcqOscarJ/src/icqosc_svcs.cpp delete mode 100644 protocols/IcqOscarJ/src/icqosc_svcs.h delete mode 100644 protocols/IcqOscarJ/src/init.cpp delete mode 100644 protocols/IcqOscarJ/src/log.cpp delete mode 100644 protocols/IcqOscarJ/src/log.h delete mode 100644 protocols/IcqOscarJ/src/loginpassword.cpp delete mode 100644 protocols/IcqOscarJ/src/oscar_filetransfer.cpp delete mode 100644 protocols/IcqOscarJ/src/oscar_filetransfer.h delete mode 100644 protocols/IcqOscarJ/src/resource.h delete mode 100644 protocols/IcqOscarJ/src/stdafx.cxx delete mode 100644 protocols/IcqOscarJ/src/stdafx.h delete mode 100644 protocols/IcqOscarJ/src/stdpackets.cpp delete mode 100644 protocols/IcqOscarJ/src/stdpackets.h delete mode 100644 protocols/IcqOscarJ/src/tlv.cpp delete mode 100644 protocols/IcqOscarJ/src/tlv.h delete mode 100644 protocols/IcqOscarJ/src/upload.cpp delete mode 100644 protocols/IcqOscarJ/src/userinfotab.cpp delete mode 100644 protocols/IcqOscarJ/src/utilities.cpp delete mode 100644 protocols/IcqOscarJ/src/utilities.h delete mode 100644 protocols/IcqOscarJ/src/version.h diff --git a/bin15/mir_full.sln b/bin15/mir_full.sln index 4bbd5fd282..74a1662fa1 100644 --- a/bin15/mir_full.sln +++ b/bin15/mir_full.sln @@ -30,8 +30,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GG", "..\protocols\Gadu-Gad EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IRC", "..\protocols\IRCG\IRC.vcxproj", "{3A12F777-56A8-42EC-BD17-8F325524241E}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ICQ", "..\protocols\IcqOscarJ\icqoscar8.vcxproj", "{01DDCB36-4DE2-405D-BC36-2C8BDEB86659}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Jabber", "..\protocols\JabberG\jabber.vcxproj", "{33276462-8313-4192-8306-13717ECCA60A}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MSN", "..\protocols\MSN\msn.vcxproj", "{7B0F213E-C15E-4219-8AE5-49DD3D3D553D}" @@ -453,6 +451,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mdbx_load", "..\tools\mdbx_ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Dbx_sqlite", "..\plugins\Dbx_sqlite\dbx_sqlite.vcxproj", "{B3494FED-FB8C-43F4-B341-F26A3460203B}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ICQ", "..\protocols\Icq10\icq10.vcxproj", "{EFB2355B-82B3-4759-B7D8-95F8E9506291}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -557,14 +557,6 @@ Global {3A12F777-56A8-42EC-BD17-8F325524241E}.Release|Win32.Build.0 = Release|Win32 {3A12F777-56A8-42EC-BD17-8F325524241E}.Release|x64.ActiveCfg = Release|x64 {3A12F777-56A8-42EC-BD17-8F325524241E}.Release|x64.Build.0 = Release|x64 - {01DDCB36-4DE2-405D-BC36-2C8BDEB86659}.Debug|Win32.ActiveCfg = Debug|Win32 - {01DDCB36-4DE2-405D-BC36-2C8BDEB86659}.Debug|Win32.Build.0 = Debug|Win32 - {01DDCB36-4DE2-405D-BC36-2C8BDEB86659}.Debug|x64.ActiveCfg = Debug|x64 - {01DDCB36-4DE2-405D-BC36-2C8BDEB86659}.Debug|x64.Build.0 = Debug|x64 - {01DDCB36-4DE2-405D-BC36-2C8BDEB86659}.Release|Win32.ActiveCfg = Release|Win32 - {01DDCB36-4DE2-405D-BC36-2C8BDEB86659}.Release|Win32.Build.0 = Release|Win32 - {01DDCB36-4DE2-405D-BC36-2C8BDEB86659}.Release|x64.ActiveCfg = Release|x64 - {01DDCB36-4DE2-405D-BC36-2C8BDEB86659}.Release|x64.Build.0 = Release|x64 {33276462-8313-4192-8306-13717ECCA60A}.Debug|Win32.ActiveCfg = Debug|Win32 {33276462-8313-4192-8306-13717ECCA60A}.Debug|Win32.Build.0 = Debug|Win32 {33276462-8313-4192-8306-13717ECCA60A}.Debug|x64.ActiveCfg = Debug|x64 @@ -2035,6 +2027,14 @@ Global {B3494FED-FB8C-43F4-B341-F26A3460203B}.Release|Win32.Build.0 = Release|Win32 {B3494FED-FB8C-43F4-B341-F26A3460203B}.Release|x64.ActiveCfg = Release|x64 {B3494FED-FB8C-43F4-B341-F26A3460203B}.Release|x64.Build.0 = Release|x64 + {EFB2355B-82B3-4759-B7D8-95F8E9506291}.Debug|Win32.ActiveCfg = Debug|Win32 + {EFB2355B-82B3-4759-B7D8-95F8E9506291}.Debug|Win32.Build.0 = Debug|Win32 + {EFB2355B-82B3-4759-B7D8-95F8E9506291}.Debug|x64.ActiveCfg = Debug|x64 + {EFB2355B-82B3-4759-B7D8-95F8E9506291}.Debug|x64.Build.0 = Debug|x64 + {EFB2355B-82B3-4759-B7D8-95F8E9506291}.Release|Win32.ActiveCfg = Release|Win32 + {EFB2355B-82B3-4759-B7D8-95F8E9506291}.Release|Win32.Build.0 = Release|Win32 + {EFB2355B-82B3-4759-B7D8-95F8E9506291}.Release|x64.ActiveCfg = Release|x64 + {EFB2355B-82B3-4759-B7D8-95F8E9506291}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -2051,7 +2051,6 @@ Global {99D26CA1-BFD4-4E77-9A1E-919E54CF33F7} = {D8EA3AE1-64AA-42ED-9F13-83F6C7B5AA55} {6DA1396F-2A44-4D5C-8442-012F71006217} = {A035B524-0F2D-45D0-BCF2-3C20279C77E2} {3A12F777-56A8-42EC-BD17-8F325524241E} = {A035B524-0F2D-45D0-BCF2-3C20279C77E2} - {01DDCB36-4DE2-405D-BC36-2C8BDEB86659} = {A035B524-0F2D-45D0-BCF2-3C20279C77E2} {33276462-8313-4192-8306-13717ECCA60A} = {A035B524-0F2D-45D0-BCF2-3C20279C77E2} {7B0F213E-C15E-4219-8AE5-49DD3D3D553D} = {A035B524-0F2D-45D0-BCF2-3C20279C77E2} {3C42510C-A29E-4A53-899C-203BFA874E0B} = {F9C41695-3353-4564-A154-58106829B19C} @@ -2163,6 +2162,7 @@ Global {EE383404-7976-4E87-BD13-A9B7B47C0C10} = {F13387B0-1C74-48EC-9AEC-65E3B9DE29E4} {63BA600E-86BF-4502-9EF0-8C090292E161} = {F13387B0-1C74-48EC-9AEC-65E3B9DE29E4} {B3494FED-FB8C-43F4-B341-F26A3460203B} = {F13387B0-1C74-48EC-9AEC-65E3B9DE29E4} + {EFB2355B-82B3-4759-B7D8-95F8E9506291} = {A035B524-0F2D-45D0-BCF2-3C20279C77E2} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {29A0C2A8-07A4-4A8B-8BED-8F7D024013D6} diff --git a/bin15/mir_icons.sln b/bin15/mir_icons.sln index 67d445bbd0..74c2feeb3e 100644 --- a/bin15/mir_icons.sln +++ b/bin15/mir_icons.sln @@ -18,8 +18,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UInfoEx_icons_ice_Z2", "..\ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Proto_Facebook", "..\protocols\FacebookRM\proto_facebook\Proto_Facebook.vcxproj", "{44298314-7DD4-4EF7-B576-30E503257223}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Proto_ICQ", "..\protocols\IcqOscarJ\proto_icq\Proto_ICQ.vcxproj", "{DB3B0449-E576-4BBB-8B08-AB9E914D39CA}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Proto_IRC", "..\protocols\IRCG\proto_irc\Proto_IRC.vcxproj", "{DD667247-3712-4355-9774-7E6ACAF2275E}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Proto_Jabber", "..\protocols\JabberG\proto_jabber\Proto_Jabber.vcxproj", "{1AA0A504-0644-4F00-A1AD-F55D69E50DD0}" @@ -30,8 +28,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Proto_GG", "..\protocols\Ga EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Proto_Twitter", "..\protocols\Twitter\proto_twitter\Proto_Twitter.vcxproj", "{A82C682E-8596-4DCA-98A6-50436194714B}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xStatus_ICQ", "..\protocols\IcqOscarJ\icq_xstatus\xStatus_ICQ.vcxproj", "{E98A8615-1082-1979-D6D8-F763F13BFCBD}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xStatus_Jabber", "..\protocols\JabberG\jabber_xstatus\xStatus_Jabber.vcxproj", "{6BBEEA1E-3C87-6CD1-F32A-027C3EC5320E}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HistoryPP_icons", "..\plugins\HistoryPlusPlus\historypp_icons\HistoryPP_icons.vcxproj", "{B2E0D5C5-D418-4962-812A-FBC5C7FFC4B6}" @@ -72,6 +68,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Proto_MinecraftDynmap", ".. EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Proto_Discord", "..\protocols\Discord\proto_discord\Proto_Discord.vcxproj", "{6B8BA5EE-3815-44A6-A13B-2A22E8B3A311}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Proto_ICQ", "..\protocols\Icq10\proto_icq\Proto_ICQ.vcxproj", "{DB3B0449-E576-4BBB-8B08-AB9E914D39CA}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xStatus_ICQ", "..\protocols\Icq10\icq_xstatus\xStatus_ICQ.vcxproj", "{E98A8615-1082-1979-D6D8-F763F13BFCBD}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -144,14 +144,6 @@ Global {44298314-7DD4-4EF7-B576-30E503257223}.Release|Win32.Build.0 = Release|Win32 {44298314-7DD4-4EF7-B576-30E503257223}.Release|x64.ActiveCfg = Release|x64 {44298314-7DD4-4EF7-B576-30E503257223}.Release|x64.Build.0 = Release|x64 - {DB3B0449-E576-4BBB-8B08-AB9E914D39CA}.Debug|Win32.ActiveCfg = Debug|Win32 - {DB3B0449-E576-4BBB-8B08-AB9E914D39CA}.Debug|Win32.Build.0 = Debug|Win32 - {DB3B0449-E576-4BBB-8B08-AB9E914D39CA}.Debug|x64.ActiveCfg = Debug|x64 - {DB3B0449-E576-4BBB-8B08-AB9E914D39CA}.Debug|x64.Build.0 = Debug|x64 - {DB3B0449-E576-4BBB-8B08-AB9E914D39CA}.Release|Win32.ActiveCfg = Release|Win32 - {DB3B0449-E576-4BBB-8B08-AB9E914D39CA}.Release|Win32.Build.0 = Release|Win32 - {DB3B0449-E576-4BBB-8B08-AB9E914D39CA}.Release|x64.ActiveCfg = Release|x64 - {DB3B0449-E576-4BBB-8B08-AB9E914D39CA}.Release|x64.Build.0 = Release|x64 {DD667247-3712-4355-9774-7E6ACAF2275E}.Debug|Win32.ActiveCfg = Debug|Win32 {DD667247-3712-4355-9774-7E6ACAF2275E}.Debug|Win32.Build.0 = Debug|Win32 {DD667247-3712-4355-9774-7E6ACAF2275E}.Debug|x64.ActiveCfg = Debug|x64 @@ -192,14 +184,6 @@ Global {A82C682E-8596-4DCA-98A6-50436194714B}.Release|Win32.Build.0 = Release|Win32 {A82C682E-8596-4DCA-98A6-50436194714B}.Release|x64.ActiveCfg = Release|x64 {A82C682E-8596-4DCA-98A6-50436194714B}.Release|x64.Build.0 = Release|x64 - {E98A8615-1082-1979-D6D8-F763F13BFCBD}.Debug|Win32.ActiveCfg = Debug|Win32 - {E98A8615-1082-1979-D6D8-F763F13BFCBD}.Debug|Win32.Build.0 = Debug|Win32 - {E98A8615-1082-1979-D6D8-F763F13BFCBD}.Debug|x64.ActiveCfg = Debug|x64 - {E98A8615-1082-1979-D6D8-F763F13BFCBD}.Debug|x64.Build.0 = Debug|x64 - {E98A8615-1082-1979-D6D8-F763F13BFCBD}.Release|Win32.ActiveCfg = Release|Win32 - {E98A8615-1082-1979-D6D8-F763F13BFCBD}.Release|Win32.Build.0 = Release|Win32 - {E98A8615-1082-1979-D6D8-F763F13BFCBD}.Release|x64.ActiveCfg = Release|x64 - {E98A8615-1082-1979-D6D8-F763F13BFCBD}.Release|x64.Build.0 = Release|x64 {6BBEEA1E-3C87-6CD1-F32A-027C3EC5320E}.Debug|Win32.ActiveCfg = Debug|Win32 {6BBEEA1E-3C87-6CD1-F32A-027C3EC5320E}.Debug|Win32.Build.0 = Debug|Win32 {6BBEEA1E-3C87-6CD1-F32A-027C3EC5320E}.Debug|x64.ActiveCfg = Debug|x64 @@ -360,6 +344,22 @@ Global {6B8BA5EE-3815-44A6-A13B-2A22E8B3A311}.Release|Win32.Build.0 = Release|Win32 {6B8BA5EE-3815-44A6-A13B-2A22E8B3A311}.Release|x64.ActiveCfg = Release|x64 {6B8BA5EE-3815-44A6-A13B-2A22E8B3A311}.Release|x64.Build.0 = Release|x64 + {DB3B0449-E576-4BBB-8B08-AB9E914D39CA}.Debug|Win32.ActiveCfg = Debug|Win32 + {DB3B0449-E576-4BBB-8B08-AB9E914D39CA}.Debug|Win32.Build.0 = Debug|Win32 + {DB3B0449-E576-4BBB-8B08-AB9E914D39CA}.Debug|x64.ActiveCfg = Debug|x64 + {DB3B0449-E576-4BBB-8B08-AB9E914D39CA}.Debug|x64.Build.0 = Debug|x64 + {DB3B0449-E576-4BBB-8B08-AB9E914D39CA}.Release|Win32.ActiveCfg = Release|Win32 + {DB3B0449-E576-4BBB-8B08-AB9E914D39CA}.Release|Win32.Build.0 = Release|Win32 + {DB3B0449-E576-4BBB-8B08-AB9E914D39CA}.Release|x64.ActiveCfg = Release|x64 + {DB3B0449-E576-4BBB-8B08-AB9E914D39CA}.Release|x64.Build.0 = Release|x64 + {E98A8615-1082-1979-D6D8-F763F13BFCBD}.Debug|Win32.ActiveCfg = Debug|Win32 + {E98A8615-1082-1979-D6D8-F763F13BFCBD}.Debug|Win32.Build.0 = Debug|Win32 + {E98A8615-1082-1979-D6D8-F763F13BFCBD}.Debug|x64.ActiveCfg = Debug|x64 + {E98A8615-1082-1979-D6D8-F763F13BFCBD}.Debug|x64.Build.0 = Debug|x64 + {E98A8615-1082-1979-D6D8-F763F13BFCBD}.Release|Win32.ActiveCfg = Release|Win32 + {E98A8615-1082-1979-D6D8-F763F13BFCBD}.Release|Win32.Build.0 = Release|Win32 + {E98A8615-1082-1979-D6D8-F763F13BFCBD}.Release|x64.ActiveCfg = Release|x64 + {E98A8615-1082-1979-D6D8-F763F13BFCBD}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/bin15/miranda32.sln b/bin15/miranda32.sln index 44671a9c78..f4488c5985 100644 --- a/bin15/miranda32.sln +++ b/bin15/miranda32.sln @@ -30,24 +30,18 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GG", "..\protocols\Gadu-Gad EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IRC", "..\protocols\IRCG\IRC.vcxproj", "{3A12F777-56A8-42EC-BD17-8F325524241E}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ICQ", "..\protocols\IcqOscarJ\icqoscar8.vcxproj", "{01DDCB36-4DE2-405D-BC36-2C8BDEB86659}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Jabber", "..\protocols\JabberG\jabber.vcxproj", "{33276462-8313-4192-8306-13717ECCA60A}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MSN", "..\protocols\MSN\msn.vcxproj", "{7B0F213E-C15E-4219-8AE5-49DD3D3D553D}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Clist_nicer", "..\plugins\clist_nicer\clist_nicer.vcxproj", "{3C42510C-A29E-4A53-899C-203BFA874E0B}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xStatus_ICQ", "..\protocols\IcqOscarJ\icq_xstatus\xStatus_ICQ.vcxproj", "{E98A8615-1082-1979-D6D8-F763F13BFCBD}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xStatus_Jabber", "..\protocols\JabberG\jabber_xstatus\xStatus_Jabber.vcxproj", "{6BBEEA1E-3C87-6CD1-F32A-027C3EC5320E}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Cln_skinedit", "..\plugins\Cln_skinedit\skinedit.vcxproj", "{987F026D-EB1F-4013-ADA8-2406ACCDA526}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Proto_GG", "..\protocols\Gadu-Gadu\proto_gg\Proto_GG.vcxproj", "{33912E32-3B68-4E2C-82AE-64C06EE987A7}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Proto_ICQ", "..\protocols\IcqOscarJ\proto_icq\Proto_ICQ.vcxproj", "{DB3B0449-E576-4BBB-8B08-AB9E914D39CA}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Proto_IRC", "..\protocols\IRCG\proto_irc\Proto_IRC.vcxproj", "{DD667247-3712-4355-9774-7E6ACAF2275E}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Proto_Jabber", "..\protocols\JabberG\proto_jabber\Proto_Jabber.vcxproj", "{1AA0A504-0644-4F00-A1AD-F55D69E50DD0}" @@ -151,6 +145,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Database", "Database", "{30 EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Dbx_sqlite", "..\plugins\Dbx_sqlite\dbx_sqlite.vcxproj", "{B3494FED-FB8C-43F4-B341-F26A3460203B}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Proto_ICQ", "..\protocols\Icq10\proto_icq\Proto_ICQ.vcxproj", "{DB3B0449-E576-4BBB-8B08-AB9E914D39CA}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xStatus_ICQ", "..\protocols\Icq10\icq_xstatus\xStatus_ICQ.vcxproj", "{E98A8615-1082-1979-D6D8-F763F13BFCBD}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ICQ", "..\protocols\Icq10\icq10.vcxproj", "{EFB2355B-82B3-4759-B7D8-95F8E9506291}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -255,14 +255,6 @@ Global {3A12F777-56A8-42EC-BD17-8F325524241E}.Release|Win32.Build.0 = Release|Win32 {3A12F777-56A8-42EC-BD17-8F325524241E}.Release|x64.ActiveCfg = Release|x64 {3A12F777-56A8-42EC-BD17-8F325524241E}.Release|x64.Build.0 = Release|x64 - {01DDCB36-4DE2-405D-BC36-2C8BDEB86659}.Debug|Win32.ActiveCfg = Debug|Win32 - {01DDCB36-4DE2-405D-BC36-2C8BDEB86659}.Debug|Win32.Build.0 = Debug|Win32 - {01DDCB36-4DE2-405D-BC36-2C8BDEB86659}.Debug|x64.ActiveCfg = Debug|x64 - {01DDCB36-4DE2-405D-BC36-2C8BDEB86659}.Debug|x64.Build.0 = Debug|x64 - {01DDCB36-4DE2-405D-BC36-2C8BDEB86659}.Release|Win32.ActiveCfg = Release|Win32 - {01DDCB36-4DE2-405D-BC36-2C8BDEB86659}.Release|Win32.Build.0 = Release|Win32 - {01DDCB36-4DE2-405D-BC36-2C8BDEB86659}.Release|x64.ActiveCfg = Release|x64 - {01DDCB36-4DE2-405D-BC36-2C8BDEB86659}.Release|x64.Build.0 = Release|x64 {33276462-8313-4192-8306-13717ECCA60A}.Debug|Win32.ActiveCfg = Debug|Win32 {33276462-8313-4192-8306-13717ECCA60A}.Debug|Win32.Build.0 = Debug|Win32 {33276462-8313-4192-8306-13717ECCA60A}.Debug|x64.ActiveCfg = Debug|x64 @@ -287,14 +279,6 @@ Global {3C42510C-A29E-4A53-899C-203BFA874E0B}.Release|Win32.Build.0 = Release|Win32 {3C42510C-A29E-4A53-899C-203BFA874E0B}.Release|x64.ActiveCfg = Release|x64 {3C42510C-A29E-4A53-899C-203BFA874E0B}.Release|x64.Build.0 = Release|x64 - {E98A8615-1082-1979-D6D8-F763F13BFCBD}.Debug|Win32.ActiveCfg = Debug|Win32 - {E98A8615-1082-1979-D6D8-F763F13BFCBD}.Debug|Win32.Build.0 = Debug|Win32 - {E98A8615-1082-1979-D6D8-F763F13BFCBD}.Debug|x64.ActiveCfg = Debug|x64 - {E98A8615-1082-1979-D6D8-F763F13BFCBD}.Debug|x64.Build.0 = Debug|x64 - {E98A8615-1082-1979-D6D8-F763F13BFCBD}.Release|Win32.ActiveCfg = Release|Win32 - {E98A8615-1082-1979-D6D8-F763F13BFCBD}.Release|Win32.Build.0 = Release|Win32 - {E98A8615-1082-1979-D6D8-F763F13BFCBD}.Release|x64.ActiveCfg = Release|x64 - {E98A8615-1082-1979-D6D8-F763F13BFCBD}.Release|x64.Build.0 = Release|x64 {6BBEEA1E-3C87-6CD1-F32A-027C3EC5320E}.Debug|Win32.ActiveCfg = Debug|Win32 {6BBEEA1E-3C87-6CD1-F32A-027C3EC5320E}.Debug|Win32.Build.0 = Debug|Win32 {6BBEEA1E-3C87-6CD1-F32A-027C3EC5320E}.Debug|x64.ActiveCfg = Debug|x64 @@ -319,14 +303,6 @@ Global {33912E32-3B68-4E2C-82AE-64C06EE987A7}.Release|Win32.Build.0 = Release|Win32 {33912E32-3B68-4E2C-82AE-64C06EE987A7}.Release|x64.ActiveCfg = Release|x64 {33912E32-3B68-4E2C-82AE-64C06EE987A7}.Release|x64.Build.0 = Release|x64 - {DB3B0449-E576-4BBB-8B08-AB9E914D39CA}.Debug|Win32.ActiveCfg = Debug|Win32 - {DB3B0449-E576-4BBB-8B08-AB9E914D39CA}.Debug|Win32.Build.0 = Debug|Win32 - {DB3B0449-E576-4BBB-8B08-AB9E914D39CA}.Debug|x64.ActiveCfg = Debug|x64 - {DB3B0449-E576-4BBB-8B08-AB9E914D39CA}.Debug|x64.Build.0 = Debug|x64 - {DB3B0449-E576-4BBB-8B08-AB9E914D39CA}.Release|Win32.ActiveCfg = Release|Win32 - {DB3B0449-E576-4BBB-8B08-AB9E914D39CA}.Release|Win32.Build.0 = Release|Win32 - {DB3B0449-E576-4BBB-8B08-AB9E914D39CA}.Release|x64.ActiveCfg = Release|x64 - {DB3B0449-E576-4BBB-8B08-AB9E914D39CA}.Release|x64.Build.0 = Release|x64 {DD667247-3712-4355-9774-7E6ACAF2275E}.Debug|Win32.ActiveCfg = Debug|Win32 {DD667247-3712-4355-9774-7E6ACAF2275E}.Debug|Win32.Build.0 = Debug|Win32 {DD667247-3712-4355-9774-7E6ACAF2275E}.Debug|x64.ActiveCfg = Debug|x64 @@ -559,6 +535,30 @@ Global {B3494FED-FB8C-43F4-B341-F26A3460203B}.Release|Win32.Build.0 = Release|Win32 {B3494FED-FB8C-43F4-B341-F26A3460203B}.Release|x64.ActiveCfg = Release|x64 {B3494FED-FB8C-43F4-B341-F26A3460203B}.Release|x64.Build.0 = Release|x64 + {DB3B0449-E576-4BBB-8B08-AB9E914D39CA}.Debug|Win32.ActiveCfg = Debug|Win32 + {DB3B0449-E576-4BBB-8B08-AB9E914D39CA}.Debug|Win32.Build.0 = Debug|Win32 + {DB3B0449-E576-4BBB-8B08-AB9E914D39CA}.Debug|x64.ActiveCfg = Debug|x64 + {DB3B0449-E576-4BBB-8B08-AB9E914D39CA}.Debug|x64.Build.0 = Debug|x64 + {DB3B0449-E576-4BBB-8B08-AB9E914D39CA}.Release|Win32.ActiveCfg = Release|Win32 + {DB3B0449-E576-4BBB-8B08-AB9E914D39CA}.Release|Win32.Build.0 = Release|Win32 + {DB3B0449-E576-4BBB-8B08-AB9E914D39CA}.Release|x64.ActiveCfg = Release|x64 + {DB3B0449-E576-4BBB-8B08-AB9E914D39CA}.Release|x64.Build.0 = Release|x64 + {E98A8615-1082-1979-D6D8-F763F13BFCBD}.Debug|Win32.ActiveCfg = Debug|Win32 + {E98A8615-1082-1979-D6D8-F763F13BFCBD}.Debug|Win32.Build.0 = Debug|Win32 + {E98A8615-1082-1979-D6D8-F763F13BFCBD}.Debug|x64.ActiveCfg = Debug|x64 + {E98A8615-1082-1979-D6D8-F763F13BFCBD}.Debug|x64.Build.0 = Debug|x64 + {E98A8615-1082-1979-D6D8-F763F13BFCBD}.Release|Win32.ActiveCfg = Release|Win32 + {E98A8615-1082-1979-D6D8-F763F13BFCBD}.Release|Win32.Build.0 = Release|Win32 + {E98A8615-1082-1979-D6D8-F763F13BFCBD}.Release|x64.ActiveCfg = Release|x64 + {E98A8615-1082-1979-D6D8-F763F13BFCBD}.Release|x64.Build.0 = Release|x64 + {EFB2355B-82B3-4759-B7D8-95F8E9506291}.Debug|Win32.ActiveCfg = Debug|Win32 + {EFB2355B-82B3-4759-B7D8-95F8E9506291}.Debug|Win32.Build.0 = Debug|Win32 + {EFB2355B-82B3-4759-B7D8-95F8E9506291}.Debug|x64.ActiveCfg = Debug|x64 + {EFB2355B-82B3-4759-B7D8-95F8E9506291}.Debug|x64.Build.0 = Debug|x64 + {EFB2355B-82B3-4759-B7D8-95F8E9506291}.Release|Win32.ActiveCfg = Release|Win32 + {EFB2355B-82B3-4759-B7D8-95F8E9506291}.Release|Win32.Build.0 = Release|Win32 + {EFB2355B-82B3-4759-B7D8-95F8E9506291}.Release|x64.ActiveCfg = Release|x64 + {EFB2355B-82B3-4759-B7D8-95F8E9506291}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -575,15 +575,12 @@ Global {99D26CA1-BFD4-4E77-9A1E-919E54CF33F7} = {6221EF9E-F53A-4381-B760-4C0208E5D597} {6DA1396F-2A44-4D5C-8442-012F71006217} = {812EF24D-9B76-4A94-ABE0-6F80C381C203} {3A12F777-56A8-42EC-BD17-8F325524241E} = {812EF24D-9B76-4A94-ABE0-6F80C381C203} - {01DDCB36-4DE2-405D-BC36-2C8BDEB86659} = {812EF24D-9B76-4A94-ABE0-6F80C381C203} {33276462-8313-4192-8306-13717ECCA60A} = {812EF24D-9B76-4A94-ABE0-6F80C381C203} {7B0F213E-C15E-4219-8AE5-49DD3D3D553D} = {812EF24D-9B76-4A94-ABE0-6F80C381C203} {3C42510C-A29E-4A53-899C-203BFA874E0B} = {6221EF9E-F53A-4381-B760-4C0208E5D597} - {E98A8615-1082-1979-D6D8-F763F13BFCBD} = {949AF443-676D-4B48-B21E-9B6FC3A4808D} {6BBEEA1E-3C87-6CD1-F32A-027C3EC5320E} = {949AF443-676D-4B48-B21E-9B6FC3A4808D} {987F026D-EB1F-4013-ADA8-2406ACCDA526} = {6221EF9E-F53A-4381-B760-4C0208E5D597} {33912E32-3B68-4E2C-82AE-64C06EE987A7} = {949AF443-676D-4B48-B21E-9B6FC3A4808D} - {DB3B0449-E576-4BBB-8B08-AB9E914D39CA} = {949AF443-676D-4B48-B21E-9B6FC3A4808D} {DD667247-3712-4355-9774-7E6ACAF2275E} = {949AF443-676D-4B48-B21E-9B6FC3A4808D} {1AA0A504-0644-4F00-A1AD-F55D69E50DD0} = {949AF443-676D-4B48-B21E-9B6FC3A4808D} {7BC6C3E7-2B17-4718-A82E-084798710E14} = {949AF443-676D-4B48-B21E-9B6FC3A4808D} @@ -613,6 +610,9 @@ Global {EE383404-7976-4E87-BD13-A9B7B47C0C10} = {30B05A85-FD7F-49CD-BBA9-0B7CE5825D52} {63BA600E-86BF-4502-9EF0-8C090292E161} = {30B05A85-FD7F-49CD-BBA9-0B7CE5825D52} {B3494FED-FB8C-43F4-B341-F26A3460203B} = {30B05A85-FD7F-49CD-BBA9-0B7CE5825D52} + {DB3B0449-E576-4BBB-8B08-AB9E914D39CA} = {949AF443-676D-4B48-B21E-9B6FC3A4808D} + {E98A8615-1082-1979-D6D8-F763F13BFCBD} = {949AF443-676D-4B48-B21E-9B6FC3A4808D} + {EFB2355B-82B3-4759-B7D8-95F8E9506291} = {812EF24D-9B76-4A94-ABE0-6F80C381C203} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {5A4CD630-DD83-4096-AA4D-7A141E43E853} diff --git a/protocols/Icq10/icq10.vcxproj b/protocols/Icq10/icq10.vcxproj index d780943e95..98fb8261e0 100644 --- a/protocols/Icq10/icq10.vcxproj +++ b/protocols/Icq10/icq10.vcxproj @@ -19,7 +19,7 @@ - Icq + ICQ {EFB2355B-82B3-4759-B7D8-95F8E9506291} diff --git a/protocols/Icq10/icq_xstatus/CMakeLists.txt b/protocols/Icq10/icq_xstatus/CMakeLists.txt new file mode 100644 index 0000000000..388679a148 --- /dev/null +++ b/protocols/Icq10/icq_xstatus/CMakeLists.txt @@ -0,0 +1,2 @@ +set(TARGET xStatus_ICQ) +include(${CMAKE_SOURCE_DIR}/cmake/icons.cmake) \ No newline at end of file diff --git a/protocols/Icq10/icq_xstatus/res/ICONS.rc b/protocols/Icq10/icq_xstatus/res/ICONS.rc new file mode 100644 index 0000000000..668fcaa7fb --- /dev/null +++ b/protocols/Icq10/icq_xstatus/res/ICONS.rc @@ -0,0 +1,132 @@ +//Microsoft Developer Studio generated resource script. +// +#include "..\src\resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_XSTATUS1 ICON "xstatus01.ico" +IDI_XSTATUS2 ICON "xstatus02.ico" +IDI_XSTATUS3 ICON "xstatus03.ico" +IDI_XSTATUS4 ICON "xstatus04.ico" +IDI_XSTATUS5 ICON "xstatus05.ico" +IDI_XSTATUS6 ICON "xstatus06.ico" +IDI_XSTATUS7 ICON "xstatus07.ico" +IDI_XSTATUS8 ICON "xstatus08.ico" +IDI_XSTATUS9 ICON "xstatus09.ico" +IDI_XSTATUS10 ICON "xstatus10.ico" +IDI_XSTATUS11 ICON "xstatus11.ico" +IDI_XSTATUS12 ICON "xstatus12.ico" +IDI_XSTATUS13 ICON "xstatus13.ico" +IDI_XSTATUS14 ICON "xstatus14.ico" +IDI_XSTATUS15 ICON "xstatus15.ico" +IDI_XSTATUS16 ICON "xstatus16.ico" +IDI_XSTATUS17 ICON "xstatus17.ico" +IDI_XSTATUS18 ICON "xstatus18.ico" +IDI_XSTATUS19 ICON "xstatus19.ico" +IDI_XSTATUS20 ICON "xstatus20.ico" +IDI_XSTATUS21 ICON "xstatus21.ico" +IDI_XSTATUS22 ICON "xstatus22.ico" +IDI_XSTATUS23 ICON "xstatus23.ico" +IDI_XSTATUS24 ICON "xstatus24.ico" +IDI_XSTATUS25 ICON "xstatus25.ico" +IDI_XSTATUS26 ICON "xstatus26.ico" +IDI_XSTATUS27 ICON "xstatus27.ico" +IDI_XSTATUS28 ICON "xstatus28.ico" +IDI_XSTATUS29 ICON "xstatus29.ico" +IDI_XSTATUS30 ICON "xstatus30.ico" +IDI_XSTATUS31 ICON "xstatus31.ico" +IDI_XSTATUS32 ICON "xstatus32.ico" +IDI_XSTATUS33 ICON "xstatus33.ico" +IDI_XSTATUS34 ICON "xstatus34.ico" +IDI_XSTATUS35 ICON "xstatus35.ico" +IDI_XSTATUS36 ICON "xstatus36.ico" +IDI_XSTATUS37 ICON "xstatus37.ico" +IDI_XSTATUS38 ICON "xstatus38.ico" +IDI_XSTATUS39 ICON "xstatus39.ico" +IDI_XSTATUS40 ICON "xstatus40.ico" +IDI_XSTATUS41 ICON "xstatus41.ico" +IDI_XSTATUS42 ICON "xstatus42.ico" +IDI_XSTATUS43 ICON "xstatus43.ico" +IDI_XSTATUS44 ICON "xstatus44.ico" +IDI_XSTATUS45 ICON "xstatus45.ico" +IDI_XSTATUS46 ICON "xstatus46.ico" +IDI_XSTATUS47 ICON "xstatus47.ico" +IDI_XSTATUS48 ICON "xstatus48.ico" +IDI_XSTATUS49 ICON "xstatus49.ico" +IDI_XSTATUS50 ICON "xstatus50.ico" +IDI_XSTATUS51 ICON "xstatus51.ico" +IDI_XSTATUS52 ICON "xstatus52.ico" +IDI_XSTATUS53 ICON "xstatus53.ico" +IDI_XSTATUS54 ICON "xstatus54.ico" +IDI_XSTATUS55 ICON "xstatus55.ico" +IDI_XSTATUS56 ICON "xstatus56.ico" +IDI_XSTATUS57 ICON "xstatus57.ico" +IDI_XSTATUS58 ICON "xstatus58.ico" +IDI_XSTATUS59 ICON "xstatus59.ico" +IDI_XSTATUS60 ICON "xstatus60.ico" +IDI_XSTATUS61 ICON "xstatus61.ico" +IDI_XSTATUS62 ICON "xstatus62.ico" +IDI_XSTATUS63 ICON "xstatus63.ico" +IDI_XSTATUS64 ICON "xstatus64.ico" +IDI_XSTATUS65 ICON "xstatus65.ico" +IDI_XSTATUS66 ICON "xstatus66.ico" +IDI_XSTATUS67 ICON "xstatus67.ico" +IDI_XSTATUS68 ICON "xstatus68.ico" +IDI_XSTATUS69 ICON "xstatus69.ico" +IDI_XSTATUS70 ICON "xstatus70.ico" +IDI_XSTATUS71 ICON "xstatus71.ico" +IDI_XSTATUS72 ICON "xstatus72.ico" +IDI_XSTATUS73 ICON "xstatus73.ico" +IDI_XSTATUS74 ICON "xstatus74.ico" +IDI_XSTATUS75 ICON "xstatus75.ico" +IDI_XSTATUS76 ICON "xstatus76.ico" +IDI_XSTATUS77 ICON "xstatus77.ico" +IDI_XSTATUS78 ICON "xstatus78.ico" +IDI_XSTATUS79 ICON "xstatus79.ico" +IDI_XSTATUS80 ICON "xstatus80.ico" +IDI_XSTATUS81 ICON "xstatus81.ico" +IDI_XSTATUS82 ICON "xstatus82.ico" +IDI_XSTATUS83 ICON "xstatus83.ico" +IDI_XSTATUS84 ICON "xstatus84.ico" +IDI_XSTATUS85 ICON "xstatus85.ico" +IDI_XSTATUS86 ICON "xstatus86.ico" + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDS_IDENTIFY "# Custom Status Icons #" +END + + + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus34.ico b/protocols/Icq10/icq_xstatus/res/Xstatus34.ico new file mode 100644 index 0000000000..94ff6c40a4 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus34.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus35.ico b/protocols/Icq10/icq_xstatus/res/Xstatus35.ico new file mode 100644 index 0000000000..c1ae60d128 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus35.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus36.ico b/protocols/Icq10/icq_xstatus/res/Xstatus36.ico new file mode 100644 index 0000000000..892feaccff Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus36.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus38.ico b/protocols/Icq10/icq_xstatus/res/Xstatus38.ico new file mode 100644 index 0000000000..65c209953c Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus38.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus39.ico b/protocols/Icq10/icq_xstatus/res/Xstatus39.ico new file mode 100644 index 0000000000..51f0d05c77 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus39.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus40.ico b/protocols/Icq10/icq_xstatus/res/Xstatus40.ico new file mode 100644 index 0000000000..f6b4998e03 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus40.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus41.ico b/protocols/Icq10/icq_xstatus/res/Xstatus41.ico new file mode 100644 index 0000000000..33a36cecff Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus41.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus42.ico b/protocols/Icq10/icq_xstatus/res/Xstatus42.ico new file mode 100644 index 0000000000..83b8bca967 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus42.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus45.ico b/protocols/Icq10/icq_xstatus/res/Xstatus45.ico new file mode 100644 index 0000000000..32d2200070 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus45.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus46.ico b/protocols/Icq10/icq_xstatus/res/Xstatus46.ico new file mode 100644 index 0000000000..5db3cfe818 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus46.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus47.ico b/protocols/Icq10/icq_xstatus/res/Xstatus47.ico new file mode 100644 index 0000000000..7cadb8087b Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus47.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus48.ico b/protocols/Icq10/icq_xstatus/res/Xstatus48.ico new file mode 100644 index 0000000000..c149ebb48d Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus48.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus49.ico b/protocols/Icq10/icq_xstatus/res/Xstatus49.ico new file mode 100644 index 0000000000..122d833056 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus49.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus50.ico b/protocols/Icq10/icq_xstatus/res/Xstatus50.ico new file mode 100644 index 0000000000..036abfa0f4 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus50.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus51.ico b/protocols/Icq10/icq_xstatus/res/Xstatus51.ico new file mode 100644 index 0000000000..201720649f Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus51.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus52.ico b/protocols/Icq10/icq_xstatus/res/Xstatus52.ico new file mode 100644 index 0000000000..bcab27a17f Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus52.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus53.ico b/protocols/Icq10/icq_xstatus/res/Xstatus53.ico new file mode 100644 index 0000000000..96f0c68511 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus53.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus54.ico b/protocols/Icq10/icq_xstatus/res/Xstatus54.ico new file mode 100644 index 0000000000..6f9e0e3067 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus54.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus56.ico b/protocols/Icq10/icq_xstatus/res/Xstatus56.ico new file mode 100644 index 0000000000..6d43039218 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus56.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus57.ico b/protocols/Icq10/icq_xstatus/res/Xstatus57.ico new file mode 100644 index 0000000000..97b9e8e44e Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus57.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus58.ico b/protocols/Icq10/icq_xstatus/res/Xstatus58.ico new file mode 100644 index 0000000000..40392dfead Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus58.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus59.ico b/protocols/Icq10/icq_xstatus/res/Xstatus59.ico new file mode 100644 index 0000000000..10af7631fd Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus59.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus60.ico b/protocols/Icq10/icq_xstatus/res/Xstatus60.ico new file mode 100644 index 0000000000..3e1970be6b Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus60.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus61.ico b/protocols/Icq10/icq_xstatus/res/Xstatus61.ico new file mode 100644 index 0000000000..fa36473e21 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus61.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus62.ico b/protocols/Icq10/icq_xstatus/res/Xstatus62.ico new file mode 100644 index 0000000000..886e5f076e Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus62.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus63.ico b/protocols/Icq10/icq_xstatus/res/Xstatus63.ico new file mode 100644 index 0000000000..907ed2801b Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus63.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus65.ico b/protocols/Icq10/icq_xstatus/res/Xstatus65.ico new file mode 100644 index 0000000000..5220b812f4 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus65.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus66.ico b/protocols/Icq10/icq_xstatus/res/Xstatus66.ico new file mode 100644 index 0000000000..6b102a202b Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus66.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus67.ico b/protocols/Icq10/icq_xstatus/res/Xstatus67.ico new file mode 100644 index 0000000000..ad4347a10d Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus67.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus68.ico b/protocols/Icq10/icq_xstatus/res/Xstatus68.ico new file mode 100644 index 0000000000..33e635fe8f Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus68.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus69.ico b/protocols/Icq10/icq_xstatus/res/Xstatus69.ico new file mode 100644 index 0000000000..128135a9f9 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus69.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus70.ico b/protocols/Icq10/icq_xstatus/res/Xstatus70.ico new file mode 100644 index 0000000000..ea98a53942 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus70.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus71.ico b/protocols/Icq10/icq_xstatus/res/Xstatus71.ico new file mode 100644 index 0000000000..74a2ba1a0e Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus71.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus72.ico b/protocols/Icq10/icq_xstatus/res/Xstatus72.ico new file mode 100644 index 0000000000..331175fb09 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus72.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus73.ico b/protocols/Icq10/icq_xstatus/res/Xstatus73.ico new file mode 100644 index 0000000000..395c83b749 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus73.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus74.ico b/protocols/Icq10/icq_xstatus/res/Xstatus74.ico new file mode 100644 index 0000000000..2d51be6ca0 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus74.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus75.ico b/protocols/Icq10/icq_xstatus/res/Xstatus75.ico new file mode 100644 index 0000000000..eb12fd82e5 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus75.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus76.ico b/protocols/Icq10/icq_xstatus/res/Xstatus76.ico new file mode 100644 index 0000000000..e7f0641f54 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus76.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus77.ico b/protocols/Icq10/icq_xstatus/res/Xstatus77.ico new file mode 100644 index 0000000000..843e9a6d89 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus77.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus78.ico b/protocols/Icq10/icq_xstatus/res/Xstatus78.ico new file mode 100644 index 0000000000..7ac7984d39 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus78.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus79.ico b/protocols/Icq10/icq_xstatus/res/Xstatus79.ico new file mode 100644 index 0000000000..c88ef8d6fc Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus79.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus81.ico b/protocols/Icq10/icq_xstatus/res/Xstatus81.ico new file mode 100644 index 0000000000..e48756ce0b Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus81.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus82.ico b/protocols/Icq10/icq_xstatus/res/Xstatus82.ico new file mode 100644 index 0000000000..68d036dd2e Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus82.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus83.ico b/protocols/Icq10/icq_xstatus/res/Xstatus83.ico new file mode 100644 index 0000000000..fd62cc5930 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus83.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus84.ico b/protocols/Icq10/icq_xstatus/res/Xstatus84.ico new file mode 100644 index 0000000000..e5b4401eca Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus84.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/Xstatus86.ico b/protocols/Icq10/icq_xstatus/res/Xstatus86.ico new file mode 100644 index 0000000000..baa5fb890a Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/Xstatus86.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus01.ico b/protocols/Icq10/icq_xstatus/res/xstatus01.ico new file mode 100644 index 0000000000..d93292e5de Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus01.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus02.ico b/protocols/Icq10/icq_xstatus/res/xstatus02.ico new file mode 100644 index 0000000000..c79590ce55 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus02.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus03.ico b/protocols/Icq10/icq_xstatus/res/xstatus03.ico new file mode 100644 index 0000000000..4e0bb4483e Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus03.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus04.ico b/protocols/Icq10/icq_xstatus/res/xstatus04.ico new file mode 100644 index 0000000000..ad969ee16f Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus04.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus05.ico b/protocols/Icq10/icq_xstatus/res/xstatus05.ico new file mode 100644 index 0000000000..8de50069f0 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus05.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus06.ico b/protocols/Icq10/icq_xstatus/res/xstatus06.ico new file mode 100644 index 0000000000..d2c3719c0e Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus06.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus07.ico b/protocols/Icq10/icq_xstatus/res/xstatus07.ico new file mode 100644 index 0000000000..b255150af3 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus07.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus08.ico b/protocols/Icq10/icq_xstatus/res/xstatus08.ico new file mode 100644 index 0000000000..efe963ed08 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus08.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus09.ico b/protocols/Icq10/icq_xstatus/res/xstatus09.ico new file mode 100644 index 0000000000..e2d763604f Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus09.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus10.ico b/protocols/Icq10/icq_xstatus/res/xstatus10.ico new file mode 100644 index 0000000000..fa35edc7cb Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus10.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus11.ico b/protocols/Icq10/icq_xstatus/res/xstatus11.ico new file mode 100644 index 0000000000..45a4e37e26 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus11.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus12.ico b/protocols/Icq10/icq_xstatus/res/xstatus12.ico new file mode 100644 index 0000000000..43141a82d7 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus12.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus13.ico b/protocols/Icq10/icq_xstatus/res/xstatus13.ico new file mode 100644 index 0000000000..0cf43cf279 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus13.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus14.ico b/protocols/Icq10/icq_xstatus/res/xstatus14.ico new file mode 100644 index 0000000000..0f642c0a4a Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus14.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus15.ico b/protocols/Icq10/icq_xstatus/res/xstatus15.ico new file mode 100644 index 0000000000..7927b650a8 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus15.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus16.ico b/protocols/Icq10/icq_xstatus/res/xstatus16.ico new file mode 100644 index 0000000000..8f9da9944a Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus16.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus17.ico b/protocols/Icq10/icq_xstatus/res/xstatus17.ico new file mode 100644 index 0000000000..a9d0eda3fd Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus17.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus18.ico b/protocols/Icq10/icq_xstatus/res/xstatus18.ico new file mode 100644 index 0000000000..4206311c4c Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus18.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus19.ico b/protocols/Icq10/icq_xstatus/res/xstatus19.ico new file mode 100644 index 0000000000..63711f9c34 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus19.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus20.ico b/protocols/Icq10/icq_xstatus/res/xstatus20.ico new file mode 100644 index 0000000000..ca25ab0335 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus20.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus21.ico b/protocols/Icq10/icq_xstatus/res/xstatus21.ico new file mode 100644 index 0000000000..d3b1bf62e3 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus21.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus22.ico b/protocols/Icq10/icq_xstatus/res/xstatus22.ico new file mode 100644 index 0000000000..d74acd732f Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus22.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus23.ico b/protocols/Icq10/icq_xstatus/res/xstatus23.ico new file mode 100644 index 0000000000..ef7a8fe956 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus23.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus24.ico b/protocols/Icq10/icq_xstatus/res/xstatus24.ico new file mode 100644 index 0000000000..549b0eaa65 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus24.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus25.ico b/protocols/Icq10/icq_xstatus/res/xstatus25.ico new file mode 100644 index 0000000000..5675d95785 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus25.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus26.ico b/protocols/Icq10/icq_xstatus/res/xstatus26.ico new file mode 100644 index 0000000000..65f14175cb Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus26.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus27.ico b/protocols/Icq10/icq_xstatus/res/xstatus27.ico new file mode 100644 index 0000000000..873695f154 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus27.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus28.ico b/protocols/Icq10/icq_xstatus/res/xstatus28.ico new file mode 100644 index 0000000000..46d29dabdd Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus28.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus29.ico b/protocols/Icq10/icq_xstatus/res/xstatus29.ico new file mode 100644 index 0000000000..b6c8410b9f Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus29.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus30.ico b/protocols/Icq10/icq_xstatus/res/xstatus30.ico new file mode 100644 index 0000000000..9776f8196c Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus30.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus31.ico b/protocols/Icq10/icq_xstatus/res/xstatus31.ico new file mode 100644 index 0000000000..92e459b096 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus31.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus32.ico b/protocols/Icq10/icq_xstatus/res/xstatus32.ico new file mode 100644 index 0000000000..37d1fa0978 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus32.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus33.ico b/protocols/Icq10/icq_xstatus/res/xstatus33.ico new file mode 100644 index 0000000000..a86ecbc90f Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus33.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus37.ico b/protocols/Icq10/icq_xstatus/res/xstatus37.ico new file mode 100644 index 0000000000..dc4c382e61 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus37.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus43.ico b/protocols/Icq10/icq_xstatus/res/xstatus43.ico new file mode 100644 index 0000000000..383b0fe278 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus43.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus44.ico b/protocols/Icq10/icq_xstatus/res/xstatus44.ico new file mode 100644 index 0000000000..38424cadb5 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus44.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus55.ico b/protocols/Icq10/icq_xstatus/res/xstatus55.ico new file mode 100644 index 0000000000..a77522c71f Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus55.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus64.ico b/protocols/Icq10/icq_xstatus/res/xstatus64.ico new file mode 100644 index 0000000000..4937cdd920 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus64.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus80.ico b/protocols/Icq10/icq_xstatus/res/xstatus80.ico new file mode 100644 index 0000000000..5db9c25f61 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus80.ico differ diff --git a/protocols/Icq10/icq_xstatus/res/xstatus85.ico b/protocols/Icq10/icq_xstatus/res/xstatus85.ico new file mode 100644 index 0000000000..20af670137 Binary files /dev/null and b/protocols/Icq10/icq_xstatus/res/xstatus85.ico differ diff --git a/protocols/Icq10/icq_xstatus/src/resource.h b/protocols/Icq10/icq_xstatus/src/resource.h new file mode 100644 index 0000000000..fecb45999e --- /dev/null +++ b/protocols/Icq10/icq_xstatus/src/resource.h @@ -0,0 +1,103 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by resources.rc +// +#define IDI_XSTATUS1 201 +#define IDI_XSTATUS2 202 +#define IDI_XSTATUS3 203 +#define IDI_XSTATUS4 204 +#define IDI_XSTATUS5 205 +#define IDI_XSTATUS6 206 +#define IDI_XSTATUS7 207 +#define IDI_XSTATUS8 208 +#define IDI_XSTATUS9 209 +#define IDI_XSTATUS10 210 +#define IDI_XSTATUS11 211 +#define IDI_XSTATUS12 212 +#define IDI_XSTATUS13 213 +#define IDI_XSTATUS14 214 +#define IDI_XSTATUS15 215 +#define IDI_XSTATUS16 216 +#define IDI_XSTATUS17 217 +#define IDI_XSTATUS18 218 +#define IDI_XSTATUS19 219 +#define IDI_XSTATUS20 220 +#define IDI_XSTATUS21 221 +#define IDI_XSTATUS22 222 +#define IDI_XSTATUS23 223 +#define IDI_XSTATUS24 224 +#define IDI_XSTATUS25 225 +#define IDI_XSTATUS26 226 +#define IDI_XSTATUS27 227 +#define IDI_XSTATUS28 228 +#define IDI_XSTATUS29 229 +#define IDI_XSTATUS30 230 +#define IDI_XSTATUS31 231 +#define IDI_XSTATUS32 232 +#define IDI_XSTATUS33 233 +#define IDI_XSTATUS34 234 +#define IDI_XSTATUS35 235 +#define IDI_XSTATUS36 236 +#define IDI_XSTATUS37 237 +#define IDI_XSTATUS38 238 +#define IDI_XSTATUS39 239 +#define IDI_XSTATUS40 240 +#define IDI_XSTATUS41 241 +#define IDI_XSTATUS42 242 +#define IDI_XSTATUS43 243 +#define IDI_XSTATUS44 244 +#define IDI_XSTATUS45 245 +#define IDI_XSTATUS46 246 +#define IDI_XSTATUS47 247 +#define IDI_XSTATUS48 248 +#define IDI_XSTATUS49 249 +#define IDI_XSTATUS50 250 +#define IDI_XSTATUS51 251 +#define IDI_XSTATUS52 252 +#define IDI_XSTATUS53 253 +#define IDI_XSTATUS54 254 +#define IDI_XSTATUS55 255 +#define IDI_XSTATUS56 256 +#define IDI_XSTATUS57 257 +#define IDI_XSTATUS58 258 +#define IDI_XSTATUS59 259 +#define IDI_XSTATUS60 260 +#define IDI_XSTATUS61 261 +#define IDI_XSTATUS62 262 +#define IDI_XSTATUS63 263 +#define IDI_XSTATUS64 264 +#define IDI_XSTATUS65 265 +#define IDI_XSTATUS66 266 +#define IDI_XSTATUS67 267 +#define IDI_XSTATUS68 268 +#define IDI_XSTATUS69 269 +#define IDI_XSTATUS70 270 +#define IDI_XSTATUS71 271 +#define IDI_XSTATUS72 272 +#define IDI_XSTATUS73 273 +#define IDI_XSTATUS74 274 +#define IDI_XSTATUS75 275 +#define IDI_XSTATUS76 276 +#define IDI_XSTATUS77 277 +#define IDI_XSTATUS78 278 +#define IDI_XSTATUS79 279 +#define IDI_XSTATUS80 280 +#define IDI_XSTATUS81 281 +#define IDI_XSTATUS82 282 +#define IDI_XSTATUS83 283 +#define IDI_XSTATUS84 284 +#define IDI_XSTATUS85 285 +#define IDI_XSTATUS86 286 + +#define IDS_IDENTIFY 102 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 113 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1026 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/protocols/Icq10/icq_xstatus/xStatus_ICQ.vcxproj b/protocols/Icq10/icq_xstatus/xStatus_ICQ.vcxproj new file mode 100644 index 0000000000..0b0e04a799 --- /dev/null +++ b/protocols/Icq10/icq_xstatus/xStatus_ICQ.vcxproj @@ -0,0 +1,28 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + xStatus_ICQ + {E98A8615-1082-1979-D6D8-F763F13BFCBD} + + + + + \ No newline at end of file diff --git a/protocols/IcqOscarJ/CMakeLists.txt b/protocols/IcqOscarJ/CMakeLists.txt deleted file mode 100644 index c5feb2c951..0000000000 --- a/protocols/IcqOscarJ/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -file(GLOB SOURCES "src/*.h" "src/*.cpp" "res/*.rc") -set(TARGET ICQ) -include(${CMAKE_SOURCE_DIR}/cmake/plugin.cmake) -target_link_libraries(${TARGET} comctl32.lib ws2_32.lib) -add_subdirectory(proto_icq) -add_subdirectory(icq_xstatus) \ No newline at end of file diff --git a/protocols/IcqOscarJ/docs/license.txt b/protocols/IcqOscarJ/docs/license.txt deleted file mode 100644 index 7f1161073d..0000000000 --- a/protocols/IcqOscarJ/docs/license.txt +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) 19yy - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) 19yy name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/protocols/IcqOscarJ/docs/readme.txt b/protocols/IcqOscarJ/docs/readme.txt deleted file mode 100644 index a683d8cd72..0000000000 --- a/protocols/IcqOscarJ/docs/readme.txt +++ /dev/null @@ -1,480 +0,0 @@ - - ICQ protocol plugin for Miranda IM (Joe) - ________________________________________ - - -About -_____ - -This Miranda IM plugin makes it possible to connect to the ICQ -instant messenger network and communicate with other ICQ users. - - -Known Problems -______________ - -- In Invisible mode, when other side is not in visible list messages are sometimes - received twice from some clients (it is a problem of that clients, they do send them - twice) - -- When synchronising server-list, users get added with await auth flag or receive added - message. The way which ICQ servers handle authorizations, we cannot do it better - when - uploading contacts to server account has to be a new one, then contacts can be added - and uploaded without auth... If the account is an old one they cannot be added without - auth if they require one. So they are added with flag awaiting auth. With the new - Manage server list contacts added contacts should never receive auth requests, but - if you have an old account they can receive added notification. - -- Some wicked firewall software can cause HTML tags (e.g. ) to be added to - incoming messages. - -- With HTTP Proxy Mode in Connection settings, neither Avatars nor File Transfer can work. - This is partly a limitation of current Miranda's network module implementation. But - File Transfer cannot work with HTTP Proxy, that is a protocol limitation. - - -TO-DO List -__________ - -0.6 - Multi-user chat - Mid-NetLib module for HTTP gateway (for Avatars to work) [icq_net] - -0.5 - Full support for sub-groups in Manage server-list dialog - Simple sub-groups support (optional) - - - -Changes -_______ - -0.5 Development - -Bugfixes: - Fixed receiving of multi-part messages (only first part was received) - Fixed processing of UTF-8 encoded status messages from QIP - Fixed AIM away message handling (caused online status to be seen as away in some clients) - -New Features - Account management (requires Miranda IM 0.8 and newer) - New user details protocol support - Added support for status notes & moods (introduced by ICQ6) - -Improvements: - URL events are now received as normal messages - Use new offline messages protocol (supports unicode) - Ability to send/receive contacts to/from ICQ6 and AIM - Server-list support now groups requests - much more faster & reliable - Improved ChangeInfo module compatibility with screen readers - Client detection improvements - Avatars are now retrieved even for offline contacts - - -0.3.9.5 - -Bugfixes: - Fixed connection problems with many contacts in server-list - Do not lose server-list contacts due to too long nicknames/comments - -Improvements: - Reinvented known spam bot blocking - - -0.3.9.4 - -Improvements: - Added ability to handle malformed UCS-2 encoded offline messages - Fixed possible local buffer overflow - - -0.3.9.3 - -Bugfixes: - Fixed problem with utf-8 message API and some message plugins (weird chars) - Fixed double Avatar pages in User Details for newer Miranda IM - - -0.3.9.2 - -Bugfixes: - Fixed possible memory corruption caused by malformed langpack - Added support for new utf-8 message API (when available) - Fixed possible rare problems with Folders plug-in support - Other minor fixes merged from trunk (0.3.10.x Development) - - -0.3.9.1 - -Bugfixes: - Fixes several minor problems - -Improvements: - Oscar File Transfers now fully handle directory transfers - - -0.3.9 - -Bugfixes: - Fixed peer-to-peer session cookie checking (was working only due to coincidence) - Fixed SMS message handling, made message parsing more consistent - Applied fix for re-requesting authorization (thx Bio) - Fixed handling of message acks & status msg replies from ICQ 6 - Fixed handling of malformed messages acks - Minor fixes for Popup plugin support - Minor protocol related tweaks - Fixed possible lags caused by typing notifications (on slow connections) - Fixed message handling (fixes bug used for stealth invisibility detection) - Several fixes to Rate Level 2 handling - more propper handling of message responses - -New Features: - Oscar File Transfers - like icq5 (including: transfer thru server, resume) - -Improvements: - Client detection improvements - Level 1 Rate management (global) - should solve problems with many contacts in list - Support for Custom Profile Folders plug-in - configurable avatars cache folder - Ability to send long offline messages (up to 4096 characters) - Messsage Error handling is now complete (no more disconnections on long msgs) - Support for Aim contacts enhanced - Better support for Miranda Ignore module - - -0.3.7.5 - -Bugfixes: - Fixed possible crash in avatar queue - Fixed special character conversion in Custom Status messages - Minor changes to client detection - - -0.3.7.4 - -Bugfixes: - Some small fixes to Custom Status API - Fixed possible buffer overrun problem in status change packet handling - Some avatar related fixes - -Improvements: - Added avatar validity checking - - -0.3.7.3 - -Bugfixes: - Fixed HTTP/HTTPS proxy support (removed useless gateway option), long messages are now sent properly - Improved status change handling (can handle broken packets) - - -0.3.7.2 - -Bugfixes: - Fixes possible buffer overflow with contact status change - Fixed migration was not working at all (should not disconnect so often on server's upgrading) - Fixed offline greeting cards were not processed properly - Fixed small protocol glitch with reverse peer-to-peer connection - - -0.3.7.1 - -Bugfixes: - Fixed possible hang on exit - Fixed avatars were not working when server port set to 0 - Made message parser more strict (fixes bug allowing stealth invisible client detection) - Fixed Popup's unicode support cannot be used in ANSI mode even if available - -Improvements: - Added new session password API - allowing plugins like Secure Login to work better - - -0.3.7 - -Bugfixes: - Our own contact in list now correctly handles events - Proxy Gateway mode is working again - File receiving from Trillian clients work again - Incorporated some bugfixes from ISee (thx Bio) - Message errors are now really displayed - Fixed memory leak in avatar code - File transfers with GnomeICU works now - Fixed changing password in ICQ Details will not save it to DB if not there - Fixed PING channel handling (caused connection drop) - Fixed bug in changeinfo with translated listbox values (thx Bio) - Fixed error handling in avatar code for uploading avatar - Fixed bug in Manage-Server list dialog, caused hang - Fixed occasional losing of messages (message parsing was incomplete) - Server-list management now stores all info - solves problems - Fixed unknown errors during login were not reported sometimes - -New Features: - Messaging support enhanced (P2P messaging supported) - Direct Connection support rewritten (with P2P messaging and reverse file-transfers) - Temporary Visible List support - New Features page in options to configure extra features - Custom statuses just like icq5 - needs clist_mw derivative (thx Big Muscle) - New custom status icons (thx Angeli-ka) - Enhanced Unicode & Ansi charsets support (each contact can have its own codepage) - AIM cross-compatability (add/remove, search by mail, status, messaging, away messages) - Secure MD5 login authentification - Revoke authorization (Advanced Feature - see further) - removes you from contact's server-list - -Improvements: - Advanced search now can use newer method (thx Bio) - Better protocol error handling - Slightly better avatar handling - Detects some spam bots & ability to block known spam bots - Merged with ChangeInfo (thx Bio) - Added possibility to remember password for session - Added possibility to retrieve away message from libgaim clients - Added status to UserInfo page - Small improvements to client detection - Uses newer capabilities format (cuts incoming traffic) - Display error messages using PopUp Plugin - Support for Iconlib Plugin - Support for unicode database module (clist data) - Level 2 Rate management for Status & Xtraz replies, Xtraz requests (useful with many contacts in list) - Full unicode/ansi support (2in1) - Support for Updater Plugin - Added support for Flash Avatars Service Plugin - Added ability to upload own flash avatar - XML file (thx Big Muscle) - - -0.3.5.3 - -Bugfixes: - Fixed losing of almost all messages (protocol change) - - -0.3.5.2 - -Bugfixes: - Error checking on offline messages was not working - Now correctly handles "import time" item (should solve some auth issues) - - -0.3.5.1 - -Bugfixes: - Renaming of server groups was not working properly - caused errors - Avatar could not be deleted (the delete button did not work) - File Transfers were not working properly in some cases (wrong cookie handling) - Avatar formats were not recognized correctly - Method of determining target dir in file receive was not solid enough - Manage server-list dialog leaked memory - Synchronize visibility items was not working properly - Our avatar image was not linked to our ContactPhoto - Added workaround for DB Blob caching issues - Fixed occasional crash on login (missing TLV validity checks) - Fixed slow update of nicks when users imported from server-list - Fixed auto info update mechanism, do not progress too fast, do not drop processing - Fixed empty groups are always hidden in Manage Server List, cannot be used either - Fixed occasional crash on avatar retrieval - limit size of image to the size of packet - If our rate is high, ignore user requests for status msgs & user details (prevents disconnection) - Added temporary solution for roughly translated ICQ 2003b russian - Manage server-list dialog could display other contacts and could crash - Basic search could search for bad uin - garbage can be in the string - Added workaround for select() malfunction - caused high CPU load - -Improvements: - If Update details from server is on, user groups are also updated - Changed System Uptime to Member since in my details - Auth system recognizes & sends UTF-8 messages - Miranda version signature improved (preparing for old signature removal in the future) - Added better error detection for offline msgs receival process - Made avatar handling more resilient to server errors - - -0.3.5 - -Bugfixes: - Server-list operations is now scheduled correctly - Newly added contact with privacy setting is not hidden anymore - Fixed unicode message receiving from Icq2Go! (messages were corrupted) - Fixed Grant authorization - not showed correctly and crashing randomly - Move to group was not working properly - On accept/decline filetransfer miranda was sometimes disconnected - Group with subgroups was deleted if empty, that messed up subgroups - Newly added contacts from server sometimes missed their group - Offline messages are no longer received older than existing ones - Now will not try to add contacts to server, which are not ours - Divided server ids to groups - caused strange behaviour if id and group id were same - Other small fixes - -New features: - Added avatar tab to user-details dialog to show avatar even without mToolTip - Linking avatar to mToolTip is now optional - My user-details now show more informations & added idle since to ICQ tab - Added support for uploading your own avatar image - -Improvements: - Rewritten Manage Server List dialog - now works perfectly (without sub-groups support) - Added partial support for subgroups (supported: rename, move, parial: add) - Added optional linking to mToolTip, link only if no image set - Added workaround for QNext client (it is not capable of type2 msgs) - Added option to turn off HTTP gateway on HTTP proxy - - -0.3.4.2 (not published) - -Bugfixes: - Fixed authorization reply - Fixed contact transfer ack - Now parses URL send ack correctly, no more timeout - Now sending ack on contacts receive - Now correctly add contact without auth if they does not require it - Fixed crash on receiving long message through P2P (very old bug) - Many other fixes (see CVS changelog for details) - -New features: - Added full unicode message support (requires SRMM Unicode) - Added support for sending and receiving Idle time. - Added reliable client identification (if not identified, gives appropriate ICQ client) - Added support for avatar images (downloading only). - Added Grant authorization option (send & recognize) - -Improvements: - Server-side list support rewritten, now uses acking, partly supports groups (without sub-groups for now). - Most cookies standardised to imitate icq5 behaviour - Basic search now automatically removes garbage from text, e.g. it can search by 123-456-789 - - -0.3.3.1 - -Bugfixes: - Could crash when receiving unicode messages. - - -0.3.3 - -Bugfixes: - Failed to send or receive files from ICQ 2003b. - Fixed a number of smaller memory leaks. - Contact e-mail info was not displayed correctly. - Failed to retrieve user details during certain circumstances. - URL messages could disappear when sent through a Direct Connection. - Nick name was not deleted from server list when local nick name was deleted. - Server side contacts could reappear after being deleted if they were on the - visible/invisible lists. - Changing status while connecting had no effect. - A bunch of other fixes that are too boring to list here, have a look at - the CVS changelog if you want the big list. - -New features: - Added support for sending and receiving Typing Notifications. - Now accepts messages formatted in unicode (note: this wont solve the problem - with displaying messages with multiple charsets). - -Improvements: - Uses plugin DLL name in various menus to make it easier to have several ICQ - plugins loaded. - More robust packet parsing reduces the risk of any future stability problems. - - -0.3.2 - -Bugfixes: - Prevent your status messages being read when you are invisible. - Small memory leak when sending an SMS. - Fixed a dumb bug that caused random disconnections from the ICQ server. - Cleaned up the code for searches and user info updates, should work better now. - AIM users in your server contact list would get added locally with uin 0. - -New features: - Added "missed message" notification. - -Improvements: - Added better error messages for message send failures. - Messages now default to the most reliable delivery method available for a given contact. - - -0.3.1 - -Bugfixes: - Fixed crash when incoming file transfer was cancelled before the transfer started - Failed to receive SMS messages sent while offline - Fixed some problems with accepting file transfers from Mirabilis clients - Increased thread safety to reduce some reported connection/disconnection problems - Fixed compability problems with sending messages to some jabber clients - Fixed some message compability problems with Trillian - Corrected some ack sending - Added a lot of safety checks to increase general stability - Plugin didnt load unless winsocks2 was installed - -New features: - Removed restrictions on UIN length for better compability with iserverd - The password can now be left empty in options, it will be asked for during login - Server port can now be left empty in options, a random port will be selected during login - Show logged on since and system uptime info in ICQ tab - -Improvements: - Reduced file size - Message sending now uses a more reliable delivery method - - - -Support and bug reporting -_________________________ - -We cannot give support on e-mail or ICQ. Please visit the Miranda IM help page at -http://www.miranda-im.org/help/ if you need help with this plugin. - -If the help page does answer your question, visit the Miranda support forum at: -http://forums.miranda-im.org/ and we will try to assist you. - -If you want to report a bug, please do so in the official bugtracker at: -http://bugs.miranda-im.org/ - - - -Contact -_______ - -Current maintainer is Joe @ Whale, jokusoftware at miranda-im.org - - - -Advanced Features -_________________ - -There are some features that are not widely used so there is no UI for them, if -you want to use them you need to do manual setup using DBE++. - -Database items (usually at Contact\ICQ): -(BYTE)UnicodeSend = 0 - to Disable unicode support (useful as a workaround for Trillian's bug) - -(WORD)CodePage - codepage for plain text encoding/decoding to/from unicode - -(WORD)InfoCodePage - codepage for interpreting user details - -Database items for Main Contact (usually at Settings\ICQ): -(DWORD)KeepAliveInterval - Period in which Keep-Alive packets are send if enabled - default is one minute - -(BYTE)PrivacyItems = 1 - adds more privacy tools to contact menu (e.g. Revoke Authorization) - - - -Credits and Thanks -__________________ - -Thanks to Angeli-Ka for nice custom status icons. - - - -License and Copyright -_____________________ - -Copyright (C) 2000-2010 Joe Kucera, Martin Öberg, Richard Hughes, Jon Keating - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. diff --git a/protocols/IcqOscarJ/icq_xstatus/CMakeLists.txt b/protocols/IcqOscarJ/icq_xstatus/CMakeLists.txt deleted file mode 100644 index 388679a148..0000000000 --- a/protocols/IcqOscarJ/icq_xstatus/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -set(TARGET xStatus_ICQ) -include(${CMAKE_SOURCE_DIR}/cmake/icons.cmake) \ No newline at end of file diff --git a/protocols/IcqOscarJ/icq_xstatus/res/ICONS.rc b/protocols/IcqOscarJ/icq_xstatus/res/ICONS.rc deleted file mode 100644 index 3c6fbe73e6..0000000000 --- a/protocols/IcqOscarJ/icq_xstatus/res/ICONS.rc +++ /dev/null @@ -1,132 +0,0 @@ -//Microsoft Developer Studio generated resource script. -// -#include "..\src\resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "winres.h" -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_XSTATUS1 ICON "xstatus01.ico" -IDI_XSTATUS2 ICON "xstatus02.ico" -IDI_XSTATUS3 ICON "xstatus03.ico" -IDI_XSTATUS4 ICON "xstatus04.ico" -IDI_XSTATUS5 ICON "xstatus05.ico" -IDI_XSTATUS6 ICON "xstatus06.ico" -IDI_XSTATUS7 ICON "xstatus07.ico" -IDI_XSTATUS8 ICON "xstatus08.ico" -IDI_XSTATUS9 ICON "xstatus09.ico" -IDI_XSTATUS10 ICON "xstatus10.ico" -IDI_XSTATUS11 ICON "xstatus11.ico" -IDI_XSTATUS12 ICON "xstatus12.ico" -IDI_XSTATUS13 ICON "xstatus13.ico" -IDI_XSTATUS14 ICON "xstatus14.ico" -IDI_XSTATUS15 ICON "xstatus15.ico" -IDI_XSTATUS16 ICON "xstatus16.ico" -IDI_XSTATUS17 ICON "xstatus17.ico" -IDI_XSTATUS18 ICON "xstatus18.ico" -IDI_XSTATUS19 ICON "xstatus19.ico" -IDI_XSTATUS20 ICON "xstatus20.ico" -IDI_XSTATUS21 ICON "xstatus21.ico" -IDI_XSTATUS22 ICON "xstatus22.ico" -IDI_XSTATUS23 ICON "xstatus23.ico" -IDI_XSTATUS24 ICON "xstatus24.ico" -IDI_XSTATUS25 ICON "xstatus25.ico" -IDI_XSTATUS26 ICON "xstatus26.ico" -IDI_XSTATUS27 ICON "xstatus27.ico" -IDI_XSTATUS28 ICON "xstatus28.ico" -IDI_XSTATUS29 ICON "xstatus29.ico" -IDI_XSTATUS30 ICON "xstatus30.ico" -IDI_XSTATUS31 ICON "xstatus31.ico" -IDI_XSTATUS32 ICON "xstatus32.ico" -IDI_XSTATUS33 ICON "xstatus33.ico" -IDI_XSTATUS34 ICON "xstatus34.ico" -IDI_XSTATUS35 ICON "xstatus35.ico" -IDI_XSTATUS36 ICON "xstatus36.ico" -IDI_XSTATUS37 ICON "xstatus37.ico" -IDI_XSTATUS38 ICON "xstatus38.ico" -IDI_XSTATUS39 ICON "xstatus39.ico" -IDI_XSTATUS40 ICON "xstatus40.ico" -IDI_XSTATUS41 ICON "xstatus41.ico" -IDI_XSTATUS42 ICON "xstatus42.ico" -IDI_XSTATUS43 ICON "xstatus43.ico" -IDI_XSTATUS44 ICON "xstatus44.ico" -IDI_XSTATUS45 ICON "xstatus45.ico" -IDI_XSTATUS46 ICON "xstatus46.ico" -IDI_XSTATUS47 ICON "xstatus47.ico" -IDI_XSTATUS48 ICON "xstatus48.ico" -IDI_XSTATUS49 ICON "xstatus49.ico" -IDI_XSTATUS50 ICON "xstatus50.ico" -IDI_XSTATUS51 ICON "xstatus51.ico" -IDI_XSTATUS52 ICON "xstatus52.ico" -IDI_XSTATUS53 ICON "xstatus53.ico" -IDI_XSTATUS54 ICON "xstatus54.ico" -IDI_XSTATUS55 ICON "xstatus55.ico" -IDI_XSTATUS56 ICON "xstatus56.ico" -IDI_XSTATUS57 ICON "xstatus57.ico" -IDI_XSTATUS58 ICON "xstatus58.ico" -IDI_XSTATUS59 ICON "xstatus59.ico" -IDI_XSTATUS60 ICON "xstatus60.ico" -IDI_XSTATUS61 ICON "xstatus61.ico" -IDI_XSTATUS62 ICON "xstatus62.ico" -IDI_XSTATUS63 ICON "xstatus63.ico" -IDI_XSTATUS64 ICON "xstatus64.ico" -IDI_XSTATUS65 ICON "xstatus65.ico" -IDI_XSTATUS66 ICON "xstatus66.ico" -IDI_XSTATUS67 ICON "xstatus67.ico" -IDI_XSTATUS68 ICON "xstatus68.ico" -IDI_XSTATUS69 ICON "xstatus69.ico" -IDI_XSTATUS70 ICON "xstatus70.ico" -IDI_XSTATUS71 ICON "xstatus71.ico" -IDI_XSTATUS72 ICON "xstatus72.ico" -IDI_XSTATUS73 ICON "xstatus73.ico" -IDI_XSTATUS74 ICON "xstatus74.ico" -IDI_XSTATUS75 ICON "xstatus75.ico" -IDI_XSTATUS76 ICON "xstatus76.ico" -IDI_XSTATUS77 ICON "xstatus77.ico" -IDI_XSTATUS78 ICON "xstatus78.ico" -IDI_XSTATUS79 ICON "xstatus79.ico" -IDI_XSTATUS80 ICON "xstatus80.ico" -IDI_XSTATUS81 ICON "xstatus81.ico" -IDI_XSTATUS82 ICON "xstatus82.ico" -IDI_XSTATUS83 ICON "xstatus83.ico" -IDI_XSTATUS84 ICON "xstatus84.ico" -IDI_XSTATUS85 ICON "xstatus85.ico" -IDI_XSTATUS86 ICON "xstatus86.ico" - - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE -BEGIN - IDS_IDENTIFY "# Custom Status Icons #" -END - - - -#endif // English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// - diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus34.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus34.ico deleted file mode 100644 index 94ff6c40a4..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus34.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus35.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus35.ico deleted file mode 100644 index c1ae60d128..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus35.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus36.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus36.ico deleted file mode 100644 index 892feaccff..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus36.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus38.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus38.ico deleted file mode 100644 index 65c209953c..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus38.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus39.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus39.ico deleted file mode 100644 index 51f0d05c77..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus39.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus40.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus40.ico deleted file mode 100644 index f6b4998e03..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus40.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus41.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus41.ico deleted file mode 100644 index 33a36cecff..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus41.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus42.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus42.ico deleted file mode 100644 index 83b8bca967..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus42.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus45.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus45.ico deleted file mode 100644 index 32d2200070..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus45.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus46.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus46.ico deleted file mode 100644 index 5db3cfe818..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus46.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus47.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus47.ico deleted file mode 100644 index 7cadb8087b..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus47.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus48.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus48.ico deleted file mode 100644 index c149ebb48d..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus48.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus49.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus49.ico deleted file mode 100644 index 122d833056..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus49.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus50.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus50.ico deleted file mode 100644 index 036abfa0f4..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus50.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus51.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus51.ico deleted file mode 100644 index 201720649f..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus51.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus52.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus52.ico deleted file mode 100644 index bcab27a17f..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus52.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus53.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus53.ico deleted file mode 100644 index 96f0c68511..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus53.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus54.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus54.ico deleted file mode 100644 index 6f9e0e3067..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus54.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus56.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus56.ico deleted file mode 100644 index 6d43039218..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus56.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus57.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus57.ico deleted file mode 100644 index 97b9e8e44e..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus57.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus58.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus58.ico deleted file mode 100644 index 40392dfead..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus58.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus59.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus59.ico deleted file mode 100644 index 10af7631fd..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus59.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus60.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus60.ico deleted file mode 100644 index 3e1970be6b..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus60.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus61.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus61.ico deleted file mode 100644 index fa36473e21..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus61.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus62.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus62.ico deleted file mode 100644 index 886e5f076e..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus62.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus63.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus63.ico deleted file mode 100644 index 907ed2801b..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus63.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus65.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus65.ico deleted file mode 100644 index 5220b812f4..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus65.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus66.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus66.ico deleted file mode 100644 index 6b102a202b..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus66.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus67.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus67.ico deleted file mode 100644 index ad4347a10d..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus67.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus68.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus68.ico deleted file mode 100644 index 33e635fe8f..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus68.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus69.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus69.ico deleted file mode 100644 index 128135a9f9..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus69.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus70.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus70.ico deleted file mode 100644 index ea98a53942..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus70.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus71.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus71.ico deleted file mode 100644 index 74a2ba1a0e..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus71.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus72.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus72.ico deleted file mode 100644 index 331175fb09..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus72.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus73.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus73.ico deleted file mode 100644 index 395c83b749..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus73.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus74.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus74.ico deleted file mode 100644 index 2d51be6ca0..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus74.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus75.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus75.ico deleted file mode 100644 index eb12fd82e5..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus75.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus76.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus76.ico deleted file mode 100644 index e7f0641f54..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus76.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus77.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus77.ico deleted file mode 100644 index 843e9a6d89..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus77.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus78.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus78.ico deleted file mode 100644 index 7ac7984d39..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus78.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus79.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus79.ico deleted file mode 100644 index c88ef8d6fc..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus79.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus81.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus81.ico deleted file mode 100644 index e48756ce0b..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus81.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus82.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus82.ico deleted file mode 100644 index 68d036dd2e..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus82.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus83.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus83.ico deleted file mode 100644 index fd62cc5930..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus83.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus84.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus84.ico deleted file mode 100644 index e5b4401eca..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus84.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus86.ico b/protocols/IcqOscarJ/icq_xstatus/res/Xstatus86.ico deleted file mode 100644 index baa5fb890a..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/Xstatus86.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus01.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus01.ico deleted file mode 100644 index d93292e5de..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus01.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus02.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus02.ico deleted file mode 100644 index c79590ce55..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus02.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus03.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus03.ico deleted file mode 100644 index 4e0bb4483e..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus03.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus04.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus04.ico deleted file mode 100644 index ad969ee16f..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus04.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus05.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus05.ico deleted file mode 100644 index 8de50069f0..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus05.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus06.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus06.ico deleted file mode 100644 index d2c3719c0e..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus06.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus07.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus07.ico deleted file mode 100644 index b255150af3..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus07.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus08.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus08.ico deleted file mode 100644 index efe963ed08..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus08.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus09.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus09.ico deleted file mode 100644 index e2d763604f..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus09.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus10.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus10.ico deleted file mode 100644 index fa35edc7cb..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus10.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus11.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus11.ico deleted file mode 100644 index 45a4e37e26..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus11.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus12.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus12.ico deleted file mode 100644 index 43141a82d7..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus12.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus13.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus13.ico deleted file mode 100644 index 0cf43cf279..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus13.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus14.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus14.ico deleted file mode 100644 index 0f642c0a4a..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus14.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus15.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus15.ico deleted file mode 100644 index 7927b650a8..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus15.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus16.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus16.ico deleted file mode 100644 index 8f9da9944a..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus16.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus17.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus17.ico deleted file mode 100644 index a9d0eda3fd..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus17.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus18.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus18.ico deleted file mode 100644 index 4206311c4c..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus18.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus19.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus19.ico deleted file mode 100644 index 63711f9c34..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus19.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus20.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus20.ico deleted file mode 100644 index ca25ab0335..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus20.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus21.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus21.ico deleted file mode 100644 index d3b1bf62e3..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus21.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus22.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus22.ico deleted file mode 100644 index d74acd732f..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus22.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus23.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus23.ico deleted file mode 100644 index ef7a8fe956..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus23.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus24.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus24.ico deleted file mode 100644 index 549b0eaa65..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus24.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus25.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus25.ico deleted file mode 100644 index 5675d95785..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus25.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus26.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus26.ico deleted file mode 100644 index 65f14175cb..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus26.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus27.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus27.ico deleted file mode 100644 index 873695f154..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus27.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus28.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus28.ico deleted file mode 100644 index 46d29dabdd..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus28.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus29.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus29.ico deleted file mode 100644 index b6c8410b9f..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus29.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus30.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus30.ico deleted file mode 100644 index 9776f8196c..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus30.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus31.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus31.ico deleted file mode 100644 index 92e459b096..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus31.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus32.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus32.ico deleted file mode 100644 index 37d1fa0978..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus32.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus33.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus33.ico deleted file mode 100644 index a86ecbc90f..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus33.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus37.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus37.ico deleted file mode 100644 index dc4c382e61..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus37.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus43.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus43.ico deleted file mode 100644 index 383b0fe278..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus43.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus44.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus44.ico deleted file mode 100644 index 38424cadb5..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus44.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus55.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus55.ico deleted file mode 100644 index a77522c71f..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus55.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus64.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus64.ico deleted file mode 100644 index 4937cdd920..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus64.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus80.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus80.ico deleted file mode 100644 index 5db9c25f61..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus80.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/res/xstatus85.ico b/protocols/IcqOscarJ/icq_xstatus/res/xstatus85.ico deleted file mode 100644 index 20af670137..0000000000 Binary files a/protocols/IcqOscarJ/icq_xstatus/res/xstatus85.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/icq_xstatus/src/resource.h b/protocols/IcqOscarJ/icq_xstatus/src/resource.h deleted file mode 100644 index ce4127c0a6..0000000000 --- a/protocols/IcqOscarJ/icq_xstatus/src/resource.h +++ /dev/null @@ -1,103 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by resources.rc -// -#define IDI_XSTATUS1 201 -#define IDI_XSTATUS2 202 -#define IDI_XSTATUS3 203 -#define IDI_XSTATUS4 204 -#define IDI_XSTATUS5 205 -#define IDI_XSTATUS6 206 -#define IDI_XSTATUS7 207 -#define IDI_XSTATUS8 208 -#define IDI_XSTATUS9 209 -#define IDI_XSTATUS10 210 -#define IDI_XSTATUS11 211 -#define IDI_XSTATUS12 212 -#define IDI_XSTATUS13 213 -#define IDI_XSTATUS14 214 -#define IDI_XSTATUS15 215 -#define IDI_XSTATUS16 216 -#define IDI_XSTATUS17 217 -#define IDI_XSTATUS18 218 -#define IDI_XSTATUS19 219 -#define IDI_XSTATUS20 220 -#define IDI_XSTATUS21 221 -#define IDI_XSTATUS22 222 -#define IDI_XSTATUS23 223 -#define IDI_XSTATUS24 224 -#define IDI_XSTATUS25 225 -#define IDI_XSTATUS26 226 -#define IDI_XSTATUS27 227 -#define IDI_XSTATUS28 228 -#define IDI_XSTATUS29 229 -#define IDI_XSTATUS30 230 -#define IDI_XSTATUS31 231 -#define IDI_XSTATUS32 232 -#define IDI_XSTATUS33 233 -#define IDI_XSTATUS34 234 -#define IDI_XSTATUS35 235 -#define IDI_XSTATUS36 236 -#define IDI_XSTATUS37 237 -#define IDI_XSTATUS38 238 -#define IDI_XSTATUS39 239 -#define IDI_XSTATUS40 240 -#define IDI_XSTATUS41 241 -#define IDI_XSTATUS42 242 -#define IDI_XSTATUS43 243 -#define IDI_XSTATUS44 244 -#define IDI_XSTATUS45 245 -#define IDI_XSTATUS46 246 -#define IDI_XSTATUS47 247 -#define IDI_XSTATUS48 248 -#define IDI_XSTATUS49 249 -#define IDI_XSTATUS50 250 -#define IDI_XSTATUS51 251 -#define IDI_XSTATUS52 252 -#define IDI_XSTATUS53 253 -#define IDI_XSTATUS54 254 -#define IDI_XSTATUS55 255 -#define IDI_XSTATUS56 256 -#define IDI_XSTATUS57 257 -#define IDI_XSTATUS58 258 -#define IDI_XSTATUS59 259 -#define IDI_XSTATUS60 260 -#define IDI_XSTATUS61 261 -#define IDI_XSTATUS62 262 -#define IDI_XSTATUS63 263 -#define IDI_XSTATUS64 264 -#define IDI_XSTATUS65 265 -#define IDI_XSTATUS66 266 -#define IDI_XSTATUS67 267 -#define IDI_XSTATUS68 268 -#define IDI_XSTATUS69 269 -#define IDI_XSTATUS70 270 -#define IDI_XSTATUS71 271 -#define IDI_XSTATUS72 272 -#define IDI_XSTATUS73 273 -#define IDI_XSTATUS74 274 -#define IDI_XSTATUS75 275 -#define IDI_XSTATUS76 276 -#define IDI_XSTATUS77 277 -#define IDI_XSTATUS78 278 -#define IDI_XSTATUS79 279 -#define IDI_XSTATUS80 280 -#define IDI_XSTATUS81 281 -#define IDI_XSTATUS82 282 -#define IDI_XSTATUS83 283 -#define IDI_XSTATUS84 284 -#define IDI_XSTATUS85 285 -#define IDI_XSTATUS86 286 - -#define IDS_IDENTIFY 102 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 113 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1026 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/protocols/IcqOscarJ/icq_xstatus/xStatus_ICQ.vcxproj b/protocols/IcqOscarJ/icq_xstatus/xStatus_ICQ.vcxproj deleted file mode 100644 index 0cad4d6682..0000000000 --- a/protocols/IcqOscarJ/icq_xstatus/xStatus_ICQ.vcxproj +++ /dev/null @@ -1,28 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - xStatus_ICQ - {E98A8615-1082-1979-D6D8-F763F13BFCBD} - - - - - \ No newline at end of file diff --git a/protocols/IcqOscarJ/icqoscar8.vcxproj b/protocols/IcqOscarJ/icqoscar8.vcxproj deleted file mode 100644 index b76e4171b6..0000000000 --- a/protocols/IcqOscarJ/icqoscar8.vcxproj +++ /dev/null @@ -1,28 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - ICQ - {01DDCB36-4DE2-405D-BC36-2C8BDEB86659} - - - - - \ No newline at end of file diff --git a/protocols/IcqOscarJ/icqoscar8.vcxproj.filters b/protocols/IcqOscarJ/icqoscar8.vcxproj.filters deleted file mode 100644 index de5ad9f66c..0000000000 --- a/protocols/IcqOscarJ/icqoscar8.vcxproj.filters +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/protocols/IcqOscarJ/proto_icq/CMakeLists.txt b/protocols/IcqOscarJ/proto_icq/CMakeLists.txt deleted file mode 100644 index 596ac21624..0000000000 --- a/protocols/IcqOscarJ/proto_icq/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -set(TARGET Proto_ICQ) -include(${CMAKE_SOURCE_DIR}/cmake/icons.cmake) \ No newline at end of file diff --git a/protocols/IcqOscarJ/proto_icq/Proto_ICQ.vcxproj b/protocols/IcqOscarJ/proto_icq/Proto_ICQ.vcxproj deleted file mode 100644 index 1f81934ccf..0000000000 --- a/protocols/IcqOscarJ/proto_icq/Proto_ICQ.vcxproj +++ /dev/null @@ -1,28 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - Proto_ICQ - {DB3B0449-E576-4BBB-8B08-AB9E914D39CA} - - - - - \ No newline at end of file diff --git a/protocols/IcqOscarJ/proto_icq/Proto_ICQ.vcxproj.filters b/protocols/IcqOscarJ/proto_icq/Proto_ICQ.vcxproj.filters deleted file mode 100644 index e39f86d5d6..0000000000 --- a/protocols/IcqOscarJ/proto_icq/Proto_ICQ.vcxproj.filters +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/protocols/IcqOscarJ/proto_icq/res/Away.ico b/protocols/IcqOscarJ/proto_icq/res/Away.ico deleted file mode 100644 index 248a3e9916..0000000000 Binary files a/protocols/IcqOscarJ/proto_icq/res/Away.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/proto_icq/res/DND.ico b/protocols/IcqOscarJ/proto_icq/res/DND.ico deleted file mode 100644 index 4833160eac..0000000000 Binary files a/protocols/IcqOscarJ/proto_icq/res/DND.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/proto_icq/res/FFC.ico b/protocols/IcqOscarJ/proto_icq/res/FFC.ico deleted file mode 100644 index e7ec4d3ae2..0000000000 Binary files a/protocols/IcqOscarJ/proto_icq/res/FFC.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/proto_icq/res/Invisible.ico b/protocols/IcqOscarJ/proto_icq/res/Invisible.ico deleted file mode 100644 index 6a337c2926..0000000000 Binary files a/protocols/IcqOscarJ/proto_icq/res/Invisible.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/proto_icq/res/NA.ico b/protocols/IcqOscarJ/proto_icq/res/NA.ico deleted file mode 100644 index ec0621dc9f..0000000000 Binary files a/protocols/IcqOscarJ/proto_icq/res/NA.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/proto_icq/res/Occupied.ico b/protocols/IcqOscarJ/proto_icq/res/Occupied.ico deleted file mode 100644 index 04ea2a5855..0000000000 Binary files a/protocols/IcqOscarJ/proto_icq/res/Occupied.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/proto_icq/res/Offline.ico b/protocols/IcqOscarJ/proto_icq/res/Offline.ico deleted file mode 100644 index af862168cd..0000000000 Binary files a/protocols/IcqOscarJ/proto_icq/res/Offline.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/proto_icq/res/Online.ico b/protocols/IcqOscarJ/proto_icq/res/Online.ico deleted file mode 100644 index 2e33305a76..0000000000 Binary files a/protocols/IcqOscarJ/proto_icq/res/Online.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/proto_icq/res/Phone.ico b/protocols/IcqOscarJ/proto_icq/res/Phone.ico deleted file mode 100644 index 74c80b66ed..0000000000 Binary files a/protocols/IcqOscarJ/proto_icq/res/Phone.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/proto_icq/res/Proto_ICQ.rc b/protocols/IcqOscarJ/proto_icq/res/Proto_ICQ.rc deleted file mode 100644 index 156b8c533c..0000000000 --- a/protocols/IcqOscarJ/proto_icq/res/Proto_ICQ.rc +++ /dev/null @@ -1,77 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "..\src\resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "afxres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// Russian (Russia) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS) -LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "..\\src\\resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""afxres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_ICON1 ICON "Offline.ico" -IDI_ICON2 ICON "Online.ico" -IDI_ICON3 ICON "Away.ico" -IDI_ICON4 ICON "Invisible.ico" -IDI_ICON5 ICON "NA.ico" -IDI_ICON6 ICON "DND.ico" -IDI_ICON7 ICON "Occupied.ico" -IDI_ICON8 ICON "FFC.ico" -IDI_ICON9 ICON "Phone.ico" -#endif // Russian (Russia) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/protocols/IcqOscarJ/proto_icq/src/resource.h b/protocols/IcqOscarJ/proto_icq/src/resource.h deleted file mode 100644 index 58048e3bc9..0000000000 --- a/protocols/IcqOscarJ/proto_icq/src/resource.h +++ /dev/null @@ -1,24 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by Proto_ICQ.rc -// -#define IDI_ICON1 105 -#define IDI_ICON2 104 -#define IDI_ICON3 128 -#define IDI_ICON4 130 -#define IDI_ICON5 131 -#define IDI_ICON6 158 -#define IDI_ICON7 159 -#define IDI_ICON8 129 -#define IDI_ICON9 1002 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 110 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/protocols/IcqOscarJ/res/expandst.ico b/protocols/IcqOscarJ/res/expandst.ico deleted file mode 100644 index a6dd1a2da9..0000000000 Binary files a/protocols/IcqOscarJ/res/expandst.ico and /dev/null differ diff --git a/protocols/IcqOscarJ/res/resources.rc b/protocols/IcqOscarJ/res/resources.rc deleted file mode 100644 index f26bf473ba..0000000000 --- a/protocols/IcqOscarJ/res/resources.rc +++ /dev/null @@ -1,544 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "..\src\resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "winres.h" -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (United States) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_EXPANDSTRINGEDIT ICON "expandst.ico" - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_ICQACCOUNT DIALOGEX 0, 0, 186, 68 -STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - LTEXT "ICQ Number:",IDC_STATIC,0,0,53,12 - EDITTEXT IDC_UIN,54,0,131,12,ES_AUTOHSCROLL - LTEXT "Password:",IDC_STATIC,0,16,53,12 - EDITTEXT IDC_PW,54,16,131,12,ES_PASSWORD | ES_AUTOHSCROLL - CONTROL "Create a new ICQ account",IDC_REGISTER,"Hyperlink",WS_TABSTOP,0,49,174,12 -END - -IDD_ASKAUTH DIALOGEX 0, 0, 186, 95 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Enter an authorization request" -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - DEFPUSHBUTTON "&Send",IDOK,34,74,50,14 - PUSHBUTTON "&Cancel",IDCANCEL,98,74,50,14 - EDITTEXT IDC_EDITAUTH,7,7,172,59,ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN -END - -IDD_LOGINPW DIALOGEX 0, 0, 157, 87 -STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Enter ICQ Password" -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - LTEXT "Enter a password for UIN %d:",IDC_INSTRUCTION,7,7,142,8 - EDITTEXT IDC_LOGINPW,17,16,122,14,ES_PASSWORD | ES_AUTOHSCROLL - CONTROL "Remember this session password",IDC_SAVEPASS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,54,120,10 - DEFPUSHBUTTON "OK",IDOK,24,66,50,14 - PUSHBUTTON "Cancel",IDCANCEL,84,66,50,14 -END - -IDD_OPT_ICQ DIALOGEX 0, 0, 310, 234 -STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - GROUPBOX "ICQ",IDC_STICQGROUP,4,0,302,93 - RTEXT "ICQ number:",IDC_STATIC11,12,14,51,8 - EDITTEXT IDC_ICQNUM,68,12,106,12,ES_AUTOHSCROLL - RTEXT "Password:",IDC_STATIC12,12,28,51,8 - EDITTEXT IDC_PASSWORD,68,26,106,12,ES_PASSWORD | ES_AUTOHSCROLL - LTEXT "Hint: If you don't enter your password here, Miranda will ask for the password every time you try to go online.",IDC_STATIC,12,43,286,19 - CONTROL "Retrieve a lost password or ICQ number",IDC_LOOKUPLINK, - "Hyperlink",WS_TABSTOP,12,78,286,8 - CONTROL "Create a new ICQ account using the ICQ website",IDC_NEWUINLINK, - "Hyperlink",WS_TABSTOP,12,66,286,8 - GROUPBOX "Connection settings",IDC_STATIC,4,94,302,136 - LTEXT "Login Server:",IDC_STATIC,12,108,55,8 - EDITTEXT IDC_ICQSERVER,68,106,106,12,ES_AUTOHSCROLL - LTEXT "Port:",IDC_STATIC,182,108,25,8 - EDITTEXT IDC_ICQPORT,208,106,29,12,ES_AUTOHSCROLL | ES_NUMBER - PUSHBUTTON "Default",IDC_RESETSERVER,241,106,56,12 - LTEXT "Hint: Use port 0 to connect on a random port. Try port 80 or port 443 if you are having problems connecting through an http proxy server.",IDC_STATIC,12,120,286,18 - CONTROL "Secure Connection (SSL)",IDC_SSL,"Button",BS_AUTOCHECKBOX | BS_TOP | WS_TABSTOP,12,138,290,10 - CONTROL "Secure (MD5) login",IDC_MD5LOGIN,"Button",BS_AUTOCHECKBOX | BS_TOP | WS_TABSTOP,12,150,290,10 - CONTROL "Legacy fix (for ICQ Groupware or IServerD only)",IDC_LEGACY, - "Button",BS_AUTOCHECKBOX | BS_TOP | WS_TABSTOP,12,162,290,10 - CONTROL "Send 'Keep-alives' (enable this if you use a proxy server and frequently get disconnected)",IDC_KEEPALIVE, - "Button",BS_AUTOCHECKBOX | BS_TOP | BS_MULTILINE | WS_TABSTOP,12,174,290,18 - CONTROL "Ignore concurrent error messages",IDC_NOERRMULTI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,192,290,10 - LTEXT "Show connection error messages:",IDC_STATIC,12,204,290,8 - CONTROL "Slider1",IDC_LOGLEVEL,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,12,216,58,10 - LTEXT "",IDC_LEVELDESCR,72,216,230,10,SS_NOPREFIX -END - -IDD_OPT_ICQCONTACTS DIALOGEX 0, 0, 310, 234 -STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - GROUPBOX "ICQ contacts stored on server",IDC_STICQGROUP,4,0,302,97 - PUSHBUTTON "Manage server's list...",IDC_UPLOADNOW,12,77,97,14 - CONTROL "Enable server-side contact lists *",IDC_ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,15,288,10 - CONTROL "Add contacts to the server's list when I add them to mine",IDC_ADDSERVER, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,33,288,10 - CONTROL "Update my contacts' details from the server *",IDC_LOADFROMSERVER, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,46,288,10 - CONTROL "Update contacts' details on the server's list when I change them in mine",IDC_SAVETOSERVER, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,59,290,10 - GROUPBOX "ICQ avatars",IDC_STATIC,4,98,302,56 - CONTROL "Enable avatar support",IDC_ENABLEAVATARS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,110,288,10 - CONTROL "Check avatar validity before saving *",IDC_STRICTAVATARCHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,124,288,10 - CONTROL "Load avatars automatically (like ICQ Lite)",IDC_AUTOLOADAVATARS, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,138,288,10 - LTEXT "These changes will take effect the next time you connect to the ICQ network.",IDC_RECONNECTREQD,10,172,290,16,NOT WS_VISIBLE - LTEXT "You cannot enable/disable the server-side contact list while you are connected to the ICQ network.",IDC_OFFLINETOENABLE,10,192,290,16,NOT WS_VISIBLE - CTEXT "Note: The options marked with an asterisk have important side-effects or caveats that may not be initially apparent documented in the help.",IDC_STATIC,10,212,290,16 -END - -IDD_OPT_ICQFEATURES DIALOGEX 0, 0, 310, 200 -STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - GROUPBOX "Messaging",IDC_STATIC,4,0,302,56 - RTEXT "Use this codepage for Ansi <-> Unicode translation:",IDC_UTFSTATIC,12,14,174,10 - COMBOBOX IDC_UTFCODEPAGE,190,12,107,51,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "Make me temporarily visible to contacts I send message to",IDC_TEMPVISIBLE, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,29,288,10 - CONTROL "Notify me when a message delivery has failed",IDC_SLOWSEND, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,41,288,10 - GROUPBOX "Peer-to-peer Messaging",IDC_STATIC,4,59,302,41 - CONTROL "Enable peer-to-peer message connections",IDC_DCENABLE, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,72,288,10 - CONTROL "Passive mode (i.e., do not initiate new connections)",IDC_DCPASSIVE, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,84,288,10 - GROUPBOX "Extra Features",IDC_STATIC,4,103,302,79 - CONTROL "Enable Custom status support for xtraz",IDC_XSTATUSENABLE, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,115,288,10 - CONTROL "Enable Custom status support for moods",IDC_MOODSENABLE, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,127,288,10 - CONTROL "Reset Custom status on status change",IDC_XSTATUSRESET, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,140,288,10 - CONTROL "Auto-retrieve Custom status details",IDC_XSTATUSAUTO, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,153,288,10 - CONTROL "Block known Spam Bots",IDC_KILLSPAMBOTS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,166,288,10 -END - -IDD_OPT_ICQPRIVACY DIALOGEX 0, 0, 310, 234 -STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - GROUPBOX "Direct connections",IDC_STATIC_DC1,4,0,302,78 - LTEXT "Allowing direct connections will expose your IP address but may be necessary for some ICQ features to work properly.",IDC_STATIC_DC2,10,12,292,17 - CONTROL "Allow direct connections with any user",IDC_DCALLOW_ANY, - "Button",BS_AUTORADIOBUTTON,21,34,281,10 - CONTROL "Allow direct connections with users on my contact list",IDC_DCALLOW_CLIST, - "Button",BS_AUTORADIOBUTTON,21,47,281,10 - CONTROL "Allow direct connections only when I authorize or initiate them",IDC_DCALLOW_AUTH, - "Button",BS_AUTORADIOBUTTON | WS_TABSTOP,21,60,281,10 - GROUPBOX "Contact List Authorization",IDC_STATIC_CLIST,4,83,302,45,WS_GROUP - CONTROL "All users may add me to their Contact List",IDC_ADD_ANY, - "Button",BS_AUTORADIOBUTTON,21,97,281,10 - CONTROL "I want to be asked when someone wants to add me to their Contact List",IDC_ADD_AUTH, - "Button",BS_AUTORADIOBUTTON | WS_TABSTOP,21,111,281,10 - GROUPBOX "Misc Settings",IDC_STATIC,4,131,302,78 - CONTROL "Allow others to view my Online / Offline status from the web (Web Aware)",IDC_WEBAWARE, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,21,144,281,10 - CONTROL "Allow others to view my primary e-mail address",IDC_PUBLISHPRIMARY, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,21,160,281,10 - CONTROL "Only reply to status message requests from users on my contact list",IDC_STATUSMSG_CLIST, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,21,176,281,10 - CONTROL "Only reply to status message request from visible contacts",IDC_STATUSMSG_VISIBLE, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,33,192,269,10 - CTEXT "Some options are grayed out because they can only be changed when you are online.",IDC_STATIC_NOTONLINE,4,215,302,8 -END - -IDD_OPT_POPUPS DIALOGEX 0, 0, 314, 251 -STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - GROUPBOX "Options",IDC_STATIC,4,4,305,71 - CONTROL "Enable popup support",IDC_POPUPS_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,19,216,10 - CONTROL "Display errors using popups",IDC_POPUPS_LOG_ENABLED, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,37,216,10 - CONTROL "Display popup when spambot is detected",IDC_POPUPS_SPAM_ENABLED, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,50,216,10 - GROUPBOX "Look && Feel",IDC_STATIC,4,80,305,160 - LTEXT "Back Color",IDC_STATIC,80,93,42,8 - LTEXT "Text Color",IDC_STATIC,130,93,40,8 - LTEXT "Timeout",IDC_STATIC,182,93,60,8 - LTEXT "Note",IDC_STATIC,12,105,60,8 - CONTROL "",IDC_POPUP_LOG0_BACKCOLOR,"ColourPicker",WS_TABSTOP,80,104,39,10 - CONTROL "",IDC_POPUP_LOG0_TEXTCOLOR,"ColourPicker",WS_TABSTOP,130,104,39,10 - EDITTEXT IDC_POPUP_LOG0_TIMEOUT,182,103,34,12,ES_AUTOHSCROLL | ES_NUMBER - LTEXT "Warning",IDC_STATIC,12,120,60,8 - CONTROL "",IDC_POPUP_LOG1_BACKCOLOR,"ColourPicker",WS_TABSTOP,80,119,39,10 - CONTROL "",IDC_POPUP_LOG1_TEXTCOLOR,"ColourPicker",WS_TABSTOP,130,119,39,10 - EDITTEXT IDC_POPUP_LOG1_TIMEOUT,182,118,34,12,ES_AUTOHSCROLL | ES_NUMBER - LTEXT "Error",IDC_STATIC,12,135,60,8 - CONTROL "",IDC_POPUP_LOG2_BACKCOLOR,"ColourPicker",WS_TABSTOP,80,134,39,10 - CONTROL "",IDC_POPUP_LOG2_TEXTCOLOR,"ColourPicker",WS_TABSTOP,130,134,39,10 - EDITTEXT IDC_POPUP_LOG2_TIMEOUT,182,133,34,12,ES_AUTOHSCROLL | ES_NUMBER - LTEXT "Fatal",IDC_STATIC,12,150,60,8 - CONTROL "",IDC_POPUP_LOG3_BACKCOLOR,"ColourPicker",WS_TABSTOP,80,149,39,10 - CONTROL "",IDC_POPUP_LOG3_TEXTCOLOR,"ColourPicker",WS_TABSTOP,130,149,39,10 - EDITTEXT IDC_POPUP_LOG3_TIMEOUT,182,148,34,12,ES_AUTOHSCROLL | ES_NUMBER - LTEXT "Spam detected",IDC_STATIC,12,165,60,8 - CONTROL "",IDC_POPUP_SPAM_BACKCOLOR,"ColourPicker",WS_TABSTOP,80,164,39,10 - CONTROL "",IDC_POPUP_SPAM_TEXTCOLOR,"ColourPicker",WS_TABSTOP,130,164,39,10 - EDITTEXT IDC_POPUP_SPAM_TIMEOUT,182,163,34,12,ES_AUTOHSCROLL | ES_NUMBER - CONTROL "&Use Windows colors",IDC_USEWINCOLORS,"Button",BS_AUTOCHECKBOX | BS_NOTIFY | WS_TABSTOP,12,183,220,8 - CONTROL "Use system &icons",IDC_USESYSICONS,"Button",BS_AUTOCHECKBOX | BS_NOTIFY | WS_TABSTOP,12,211,220,8 - DEFPUSHBUTTON "Previe&w",IDC_PREVIEW,247,192,52,12 - CONTROL "Use default colors",IDC_USEDEFCOLORS,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,12,196,221,10 -END - -IDD_INFO_ICQ DIALOGEX 0, 0, 222, 132 -STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - LTEXT "UIN:",IDC_UINSTATIC,5,5,71,8 - EDITTEXT IDC_UIN,74,5,143,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER - LTEXT "External IP:",IDC_STATIC,5,18,71,8 - EDITTEXT IDC_IP,74,18,74,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER - LTEXT "Internal IP:",IDC_STATIC,5,31,71,8 - EDITTEXT IDC_REALIP,74,31,139,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER - LTEXT "Port:",IDC_STATIC,5,44,71,8 - EDITTEXT IDC_PORT,74,44,141,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER - LTEXT "Protocol Version:",IDC_STATIC,5,57,71,8 - EDITTEXT IDC_VERSION,74,57,142,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER - LTEXT "User Client:",IDC_STATIC,5,70,71,8 - EDITTEXT IDC_MIRVER,74,70,141,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER - LTEXT "Online since:",IDC_STATIC,5,83,71,8 - EDITTEXT IDC_ONLINESINCE,74,83,139,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER - LTEXT "System up since:",IDC_SUPTIME,5,96,71,8 - EDITTEXT IDC_SYSTEMUPTIME,74,96,139,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER - LTEXT "Idle since:",IDC_STATIC,5,109,71,8 - EDITTEXT IDC_IDLETIME,74,109,139,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER - LTEXT "Status:",IDC_STATIC,5,122,71,8 - EDITTEXT IDC_STATUS,74,122,139,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER -END - -IDD_ICQADVANCEDSEARCH DIALOGEX 0, 0, 335, 247 -STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_BORDER -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - GROUPBOX "Summary",IDC_SUMMARYGROUP,8,3,156,131 - LTEXT "Nickname:",IDC_STATIC,15,14,50,8 - EDITTEXT IDC_NICK,65,12,91,12,ES_AUTOHSCROLL - LTEXT "First name:",IDC_STATIC,15,29,50,8 - EDITTEXT IDC_FIRSTNAME,65,27,91,12,ES_AUTOHSCROLL - LTEXT "Last name:",IDC_STATIC,15,44,50,8 - EDITTEXT IDC_LASTNAME,65,42,91,12,ES_AUTOHSCROLL - LTEXT "E-mail:",IDC_STATIC,15,59,50,8 - EDITTEXT IDC_EMAIL,65,57,91,12,ES_AUTOHSCROLL - LTEXT "Gender:",IDC_STATIC,15,74,50,8 - COMBOBOX IDC_GENDER,65,72,91,51,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Age:",IDC_STATIC,15,89,50,8 - COMBOBOX IDC_AGERANGE,65,87,91,90,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Marital status:",IDC_STATIC,15,104,50,8 - COMBOBOX IDC_MARITALSTATUS,65,102,91,90,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Keywords:",IDC_STATIC,15,119,50,8 - EDITTEXT IDC_KEYWORDS,65,117,91,12,ES_AUTOHSCROLL - GROUPBOX "Work",IDC_WORKGROUP,8,138,156,102 - LTEXT "Occupation:",IDC_STATIC,15,149,50,8 - COMBOBOX IDC_WORKFIELD,65,147,91,93,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Company:",IDC_STATIC,15,164,50,8 - EDITTEXT IDC_COMPANY,65,162,91,12,ES_AUTOHSCROLL - LTEXT "Department:",IDC_STATIC,15,179,50,8 - EDITTEXT IDC_DEPARTMENT,65,177,91,12,ES_AUTOHSCROLL - LTEXT "Position:",IDC_STATIC,15,194,50,8 - EDITTEXT IDC_POSITION,65,192,91,12,ES_AUTOHSCROLL - LTEXT "Organization:",IDC_STATIC,15,209,50,8 - COMBOBOX IDC_ORGANISATION,65,207,91,99,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Keywords:",IDC_STATIC,24,224,41,8 - EDITTEXT IDC_ORGKEYWORDS,65,222,91,12,ES_AUTOHSCROLL - GROUPBOX "Location",IDC_LOCATIONGROUP,171,3,156,72 - LTEXT "Language:",IDC_STATIC,178,14,50,8 - COMBOBOX IDC_LANGUAGE,228,12,91,113,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Country:",IDC_STATIC,178,29,50,8 - COMBOBOX IDC_COUNTRY,228,27,91,172,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "State:",IDC_STATIC,178,44,50,8 - EDITTEXT IDC_STATE,228,42,91,12,ES_AUTOHSCROLL - LTEXT "City:",IDC_STATIC,178,59,50,8 - EDITTEXT IDC_CITY,228,57,91,12,ES_AUTOHSCROLL - GROUPBOX "Background info",IDC_BACKGROUNDGROUP,171,79,156,116 - LTEXT "Interests",IDC_STATIC,178,90,50,8 - LTEXT "Category:",IDC_STATIC,188,101,40,8 - COMBOBOX IDC_INTERESTSCAT,228,99,91,95,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Keywords:",IDC_STATIC,188,116,40,8 - EDITTEXT IDC_INTERESTSKEY,228,114,91,12,ES_AUTOHSCROLL - LTEXT "Past",IDC_STATIC,178,129,50,8 - LTEXT "Category:",IDC_STATIC,188,140,40,8 - COMBOBOX IDC_PASTCAT,228,138,91,97,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Keywords:",IDC_STATIC,188,155,40,8 - EDITTEXT IDC_PASTKEY,228,153,91,12,ES_AUTOHSCROLL - LTEXT "Homepage",IDC_STATIC,178,168,50,8 - LTEXT "Category:",IDC_STATIC,188,179,40,8,NOT WS_VISIBLE - COMBOBOX IDC_HOMEPAGECAT,228,177,91,56,CBS_DROPDOWNLIST | CBS_SORT | NOT WS_VISIBLE | WS_VSCROLL | WS_TABSTOP - LTEXT "Keywords:",IDC_STATIC,188,179,40,8 - EDITTEXT IDC_HOMEPAGEKEY,228,177,91,12,ES_AUTOHSCROLL - GROUPBOX "Other",IDC_OTHERGROUP,171,199,156,41 - CONTROL "Search online users only",IDC_ONLINEONLY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,178,217,142,10 -END - -IDD_ICQUPLOADLIST DIALOGEX 0, 0, 358, 241 -STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU -EXSTYLE WS_EX_CONTROLPARENT -CAPTION "Manage ICQ Server Contacts" -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - LTEXT "Select contacts to store:",IDC_STATIC11,5,5,91,8 - CONTROL "",IDC_CLIST,"CListControl",WS_TABSTOP | 0x3da,5,14,155,222,WS_EX_CLIENTEDGE - DEFPUSHBUTTON "Synchronize",IDOK,226,222,68,14 - PUSHBUTTON "Cancel",IDCANCEL,298,222,55,14 - LISTBOX IDC_LOG,169,5,184,213,NOT LBS_NOTIFY | LBS_NOINTEGRALHEIGHT | LBS_NOSEL | WS_VSCROLL | WS_TABSTOP -END - -IDD_SETXSTATUS DIALOGEX 0, 0, 189, 98 -STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU -EXSTYLE WS_EX_CONTROLPARENT -CAPTION "Custom Status ""%s"" Details" -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - DEFPUSHBUTTON "Closing in %d",IDOK,62,79,65,14 - LTEXT "Title:",IDC_XTITLE_STATIC,5,0,179,8 - EDITTEXT IDC_XTITLE,5,9,179,13,ES_AUTOHSCROLL - LTEXT "Message:",IDC_XMSG_STATIC,5,22,179,8 - EDITTEXT IDC_XMSG,5,31,179,43,ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL - CTEXT "Retrieving custom status details...",IDC_RETRXSTATUS,5,0,179,75,SS_CENTERIMAGE | NOT WS_VISIBLE -END - -IDD_INFO_CHANGEINFO DIALOGEX 0, 0, 222, 132 -STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - CONTROL "",IDC_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_NOCOLUMNHEADER | WS_BORDER | WS_TABSTOP,2,2,218,113 - PUSHBUTTON "&Save changes",IDC_SAVE,140,117,80,13,WS_DISABLED - EDITTEXT IDC_UPLOADING,2,118,127,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_VISIBLE | NOT WS_BORDER -END - -IDD_PWCONFIRM DIALOGEX 0, 0, 167, 78 -STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -EXSTYLE WS_EX_CONTROLPARENT -CAPTION "Confirm Password Change" -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - LTEXT "Please re-type your new password:",IDC_STATIC,5,5,157,9 - EDITTEXT IDC_PASSWORD,5,15,157,12,ES_PASSWORD | ES_AUTOHSCROLL - LTEXT "Enter your current password:",IDC_STATIC,5,32,157,9 - EDITTEXT IDC_OLDPASS,5,42,157,12,ES_PASSWORD | ES_AUTOHSCROLL - DEFPUSHBUTTON "OK",IDOK,26,59,50,14 - PUSHBUTTON "Cancel",IDCANCEL,91,59,50,14 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_ICQACCOUNT, DIALOG - BEGIN - LEFTMARGIN, 7 - TOPMARGIN, 7 - END - - IDD_ASKAUTH, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 179 - TOPMARGIN, 7 - BOTTOMMARGIN, 88 - END - - IDD_LOGINPW, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 149 - TOPMARGIN, 7 - BOTTOMMARGIN, 80 - END - - IDD_OPT_ICQ, DIALOG - BEGIN - LEFTMARGIN, 4 - VERTGUIDE, 12 - VERTGUIDE, 174 - VERTGUIDE, 302 - TOPMARGIN, 4 - HORZGUIDE, 120 - END - - IDD_OPT_ICQCONTACTS, DIALOG - BEGIN - LEFTMARGIN, 4 - VERTGUIDE, 12 - VERTGUIDE, 302 - TOPMARGIN, 4 - BOTTOMMARGIN, 232 - END - - IDD_OPT_ICQFEATURES, DIALOG - BEGIN - LEFTMARGIN, 4 - VERTGUIDE, 12 - TOPMARGIN, 7 - END - - IDD_OPT_ICQPRIVACY, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 307 - TOPMARGIN, 7 - BOTTOMMARGIN, 233 - END - - IDD_OPT_POPUPS, DIALOG - BEGIN - LEFTMARGIN, 4 - RIGHTMARGIN, 309 - VERTGUIDE, 12 - VERTGUIDE, 80 - VERTGUIDE, 130 - VERTGUIDE, 182 - TOPMARGIN, 4 - HORZGUIDE, 19 - HORZGUIDE, 37 - HORZGUIDE, 104 - HORZGUIDE, 203 - END - - IDD_INFO_ICQ, DIALOG - BEGIN - LEFTMARGIN, 5 - RIGHTMARGIN, 217 - VERTGUIDE, 61 - TOPMARGIN, 5 - BOTTOMMARGIN, 129 - HORZGUIDE, 22 - HORZGUIDE, 35 - HORZGUIDE, 48 - HORZGUIDE, 61 - HORZGUIDE, 74 - END - - IDD_ICQADVANCEDSEARCH, DIALOG - BEGIN - LEFTMARGIN, 8 - RIGHTMARGIN, 327 - VERTGUIDE, 15 - VERTGUIDE, 25 - VERTGUIDE, 65 - VERTGUIDE, 156 - VERTGUIDE, 178 - VERTGUIDE, 228 - VERTGUIDE, 319 - TOPMARGIN, 5 - BOTTOMMARGIN, 239 - END - - IDD_ICQUPLOADLIST, DIALOG - BEGIN - LEFTMARGIN, 5 - RIGHTMARGIN, 353 - TOPMARGIN, 5 - BOTTOMMARGIN, 236 - END - - IDD_INFO_CHANGEINFO, DIALOG - BEGIN - LEFTMARGIN, 2 - RIGHTMARGIN, 220 - TOPMARGIN, 2 - BOTTOMMARGIN, 130 - END - - IDD_PWCONFIRM, DIALOG - BEGIN - LEFTMARGIN, 5 - RIGHTMARGIN, 162 - TOPMARGIN, 5 - BOTTOMMARGIN, 73 - END -END -#endif // APSTUDIO_INVOKED - - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "..\\src\\resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""winres.h""\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - -#endif // English (United States) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/protocols/IcqOscarJ/res/version.rc b/protocols/IcqOscarJ/res/version.rc deleted file mode 100644 index 5a5ddd63ed..0000000000 --- a/protocols/IcqOscarJ/res/version.rc +++ /dev/null @@ -1,9 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#ifdef APSTUDIO_INVOKED -#error this file is not editable by Microsoft Visual C++ -#endif //APSTUDIO_INVOKED - -#include "..\src\version.h" - -#include "..\..\build\Version.rc" diff --git a/protocols/IcqOscarJ/src/askauthentication.cpp b/protocols/IcqOscarJ/src/askauthentication.cpp deleted file mode 100644 index 1afcac4f89..0000000000 --- a/protocols/IcqOscarJ/src/askauthentication.cpp +++ /dev/null @@ -1,82 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2008 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -class AskAuthProcDlg : public CProtoDlgBase -{ - MCONTACT m_hContact; - - CCtrlEdit m_auth; - CCtrlButton m_btnOk; - -public: - AskAuthProcDlg(CIcqProto *_ppro, MCONTACT _hContact) : - CProtoDlgBase(_ppro, IDD_ASKAUTH), - m_hContact(_hContact), - m_auth(this, IDC_EDITAUTH), - m_btnOk(this, IDOK) - { - m_autoClose = CLOSE_ON_CANCEL; // let onOk() to close window manually - m_btnOk.OnClick = Callback(this, &AskAuthProcDlg::onOk); - } - - bool OnInitDialog() override - { - if (!m_hContact || !m_proto->icqOnline()) - EndDialog(m_hwnd, 0); - - m_auth.SendMsg(EM_LIMITTEXT, 255, 0); - m_auth.SetText(TranslateT("Please authorize me to add you to my contact list.")); - return true; - } - - void onOk(CCtrlButton*) - { - if (!m_proto->icqOnline()) - return; - - DWORD dwUin; - uid_str szUid; - if (m_proto->getContactUid(m_hContact, &dwUin, &szUid)) - return; // Invalid contact - - char *szReason = GetWindowTextUtf(m_auth.GetHwnd()); - m_proto->icq_sendAuthReqServ(dwUin, szUid, szReason); - SAFE_FREE((void**)&szReason); - - // auth bug fix (thx Bio) - if (m_proto->m_bSsiEnabled && dwUin) - m_proto->resetServContactAuthState(m_hContact); - - EndDialog(m_hwnd, 0); - } -}; - -INT_PTR CIcqProto::RequestAuthorization(WPARAM wParam, LPARAM) -{ - AskAuthProcDlg(this, wParam).DoModal(); - return 0; -} diff --git a/protocols/IcqOscarJ/src/capabilities.cpp b/protocols/IcqOscarJ/src/capabilities.cpp deleted file mode 100644 index bdde98f6d8..0000000000 --- a/protocols/IcqOscarJ/src/capabilities.cpp +++ /dev/null @@ -1,247 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// Contains helper functions to handle oscar user capabilities. Scanning and -// adding capabilities are assumed to be more timecritical than looking up -// capabilites. During the login sequence there could possibly be many hundred -// scans but only a few lookups. So when you add or change something in this -// code you must have this in mind, dont do anything that will slow down the -// adding process too much. -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -struct icq_capability -{ - DWORD capID; // A bitmask, we use it in order to save database space - capstr capCLSID; // A binary representation of a oscar capability -}; - -static const icq_capability CapabilityRecord[] = -{ - { CAPF_SRV_RELAY, { CAP_SRV_RELAY }}, - { CAPF_UTF, { CAP_UTF }}, - { CAPF_RTF, { CAP_RTF }}, - { CAPF_CONTACTS, { CAP_CONTACTS }}, - { CAPF_TYPING, { CAP_TYPING }}, - { CAPF_ICQDIRECT, { CAP_ICQDIRECT }}, - { CAPF_XTRAZ, { CAP_XTRAZ }}, - { CAPF_OSCAR_FILE, { CAP_OSCAR_FILE }} -}; - -// Mask of all handled capabilities' flags -#define CapabilityFlagsMask (CAPF_SRV_RELAY | CAPF_UTF | CAPF_RTF | CAPF_CONTACTS | CAPF_TYPING | CAPF_ICQDIRECT | CAPF_XTRAZ | CAPF_OSCAR_FILE) - - -#ifdef _DEBUG -struct icq_capability_name -{ - DWORD capID; - const char* capName; -}; - -static const icq_capability_name CapabilityNames[] = -{ - { CAPF_SRV_RELAY, "ServerRelay"}, - { CAPF_UTF, "UTF8 Messages"}, - { CAPF_RTF, "RTF Messages"}, - { CAPF_CONTACTS, "Contact Transfer"}, - { CAPF_TYPING, "Typing Notifications"}, - { CAPF_ICQDIRECT, "Direct Connections"}, - { CAPF_XTRAZ, "Xtraz"}, - { CAPF_OSCAR_FILE, "File Transfers"}, - { CAPF_STATUS_MESSAGES,"Individual Status Messages"}, - { CAPF_STATUS_MOOD, "Mood"}, - { CAPF_XSTATUS, "Custom Status"} -}; - -void NetLog_CapabilityChange(CIcqProto *ppro, const char *szChange, DWORD fdwCapabilities) -{ - char szBuffer[MAX_PATH] = { 0 }; - - if (!fdwCapabilities) return; - - for (auto &it : CapabilityNames) { - // Check if the current capability is present - if ((fdwCapabilities & it.capID) == it.capID) { - if (mir_strlen(szBuffer)) - mir_strcat(szBuffer, ", "); - mir_strcat(szBuffer, it.capName); - } - } - // Log the change - ppro->debugLogA("Capabilities: %s %s", szChange, szBuffer); -} -#endif - -// Deletes all oscar capabilities for a given contact -void CIcqProto::ClearAllContactCapabilities(MCONTACT hContact) -{ - setDword(hContact, DBSETTING_CAPABILITIES, 0); -} - -// Deletes one or many oscar capabilities for a given contact -void CIcqProto::ClearContactCapabilities(MCONTACT hContact, DWORD fdwCapabilities) -{ - // Get current capability flags - DWORD fdwContactCaps = getDword(hContact, DBSETTING_CAPABILITIES, 0); - if (fdwContactCaps != (fdwContactCaps & ~fdwCapabilities)) { -#ifdef _DEBUG - NetLog_CapabilityChange(this, "Removed", fdwCapabilities & fdwContactCaps); -#endif - // Clear unwanted capabilities - fdwContactCaps &= ~fdwCapabilities; - - // And write it back to disk - setDword(hContact, DBSETTING_CAPABILITIES, fdwContactCaps); - } -} - -// Sets one or many oscar capabilities for a given contact -void CIcqProto::SetContactCapabilities(MCONTACT hContact, DWORD fdwCapabilities) -{ - // Get current capability flags - DWORD fdwContactCaps = getDword(hContact, DBSETTING_CAPABILITIES, 0); - if (fdwContactCaps != (fdwContactCaps | fdwCapabilities)) { -#ifdef _DEBUG - NetLog_CapabilityChange(this, "Added", fdwCapabilities & ~fdwContactCaps); -#endif - // Update them - fdwContactCaps |= fdwCapabilities; - - // And write it back to disk - setDword(hContact, DBSETTING_CAPABILITIES, fdwContactCaps); - } -} - -// Returns true if the given contact supports the requested capabilites -BOOL CIcqProto::CheckContactCapabilities(MCONTACT hContact, DWORD fdwCapabilities) -{ - // Get current capability flags - DWORD fdwContactCaps = getDword(hContact, DBSETTING_CAPABILITIES, 0); - - // Check if all requested capabilities are supported - if ((fdwContactCaps & fdwCapabilities) == fdwCapabilities) - return TRUE; - - return FALSE; -} - - -// Scan capability against the capability buffer -capstr* MatchCapability(BYTE *buf, size_t bufsize, const capstr *cap, size_t capsize) -{ - while (bufsize >= BINARY_CAP_SIZE) { // search the buffer for a capability - if (!memcmp(buf, cap, capsize)) - return (capstr*)buf; // give found capability for version info - - buf += BINARY_CAP_SIZE; - bufsize -= BINARY_CAP_SIZE; - } - return nullptr; -} - - -// Scan short capability against the capability buffer -capstr* MatchShortCapability(BYTE *buf, size_t bufsize, const shortcapstr *cap) -{ - capstr fullCap; - memcpy(fullCap, capShortCaps, BINARY_CAP_SIZE); - fullCap[2] = (*cap)[0]; - fullCap[3] = (*cap)[1]; - - return MatchCapability(buf, bufsize, &fullCap, BINARY_CAP_SIZE); -} - -// Scans a binary buffer for OSCAR capabilities. -DWORD GetCapabilitiesFromBuffer(BYTE *pBuffer, int nLength) -{ - DWORD fdwCaps = 0; - - // Calculate the number of records - int nRecordSize = _countof(CapabilityRecord); - - // Loop over all capabilities in the buffer and - // compare them to our own record of capabilities - for (int nIndex = 0; nIndex < nRecordSize; nIndex++) { - // Match, add capability flag - if (MatchCapability(pBuffer, nLength, &CapabilityRecord[nIndex].capCLSID, BINARY_CAP_SIZE)) - fdwCaps |= CapabilityRecord[nIndex].capID; - } - - return fdwCaps; -} - -// Scans a binary buffer for oscar capabilities and adds them to the contact. -// You probably want to call ClearAllContactCapabilities() first. -void CIcqProto::AddCapabilitiesFromBuffer(MCONTACT hContact, BYTE *pBuffer, int nLength) -{ - // Get current capability flags - DWORD fdwContactCaps = getDword(hContact, DBSETTING_CAPABILITIES, 0); - // Get capability flags from buffer - DWORD fdwCapabilities = GetCapabilitiesFromBuffer(pBuffer, nLength); - - if (fdwContactCaps != (fdwContactCaps | fdwCapabilities)) { -#ifdef _DEBUG - NetLog_CapabilityChange(this, "Added", fdwCapabilities & ~fdwContactCaps); -#endif - // Add capability flags from buffer - fdwContactCaps |= fdwCapabilities; - - // And write them back to database - setDword(hContact, DBSETTING_CAPABILITIES, fdwContactCaps); - } -} - -// Scans a binary buffer for oscar capabilities and adds them to the contact. -// You probably want to call ClearAllContactCapabilities() first. -void CIcqProto::SetCapabilitiesFromBuffer(MCONTACT hContact, BYTE *pBuffer, int nLength, BOOL bReset) -{ - // Get current capability flags - DWORD fdwContactCaps = bReset ? 0 : getDword(hContact, DBSETTING_CAPABILITIES, 0); - // Get capability flags from buffer - DWORD fdwCapabilities = GetCapabilitiesFromBuffer(pBuffer, nLength); - -#ifdef _DEBUG - if (bReset) - NetLog_CapabilityChange(this, "Set", fdwCapabilities); - else { - NetLog_CapabilityChange(this, "Removed", fdwContactCaps & ~fdwCapabilities & CapabilityFlagsMask); - NetLog_CapabilityChange(this, "Added", fdwCapabilities & ~fdwContactCaps); - } -#endif - - if (fdwCapabilities != (fdwContactCaps & ~CapabilityFlagsMask)) { - // Get current unmanaged capability flags - fdwContactCaps &= ~CapabilityFlagsMask; - - // Add capability flags from buffer - fdwContactCaps |= fdwCapabilities; - - // And write them back to database - setDword(hContact, DBSETTING_CAPABILITIES, fdwContactCaps); - } -} diff --git a/protocols/IcqOscarJ/src/capabilities.h b/protocols/IcqOscarJ/src/capabilities.h deleted file mode 100644 index 860c33fcc8..0000000000 --- a/protocols/IcqOscarJ/src/capabilities.h +++ /dev/null @@ -1,43 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// Contains helper functions to handle OSCAR user capabilities. -// ----------------------------------------------------------------------------- - -#ifndef __CAPABILITIES_H -#define __CAPABILITIES_H - -// capabilities -typedef BYTE capstr[BINARY_CAP_SIZE]; -typedef BYTE shortcapstr[BINARY_SHORT_CAP_SIZE]; - -extern const capstr capShortCaps; - -capstr* MatchCapability(BYTE *buf, size_t bufsize, const capstr *cap, size_t capsize = BINARY_CAP_SIZE); -capstr* MatchShortCapability(BYTE *buf, size_t bufsize, const shortcapstr *cap); - - -#endif /* __CAPABILITIES_H */ diff --git a/protocols/IcqOscarJ/src/chan_01login.cpp b/protocols/IcqOscarJ/src/chan_01login.cpp deleted file mode 100644 index 9f7f99f755..0000000000 --- a/protocols/IcqOscarJ/src/chan_01login.cpp +++ /dev/null @@ -1,81 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2009 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -void CIcqProto::handleLoginChannel(BYTE*, size_t, serverthread_info *info) -{ - icq_packet packet; - - debugLogA("Received SRV_HELLO from %s", info->isLoginServer ? "login server" : "communication server"); - - // isLoginServer is "1" if we just received SRV_HELLO - if (info->isLoginServer) { - if (m_bSecureLogin) { - debugLogA("Sending %s to %s", "CLI_HELLO", "login server"); - - packet.wLen = 12; - write_flap(&packet, ICQ_LOGIN_CHAN); - packDWord(&packet, 0x00000001); - packTLVDWord(&packet, 0x8003, 0x00100000); // unknown - sendServPacket(&packet); // greet login server - - char szUin[UINMAXLEN]; - size_t wUinLen = mir_strlen(strUID(m_dwLocalUIN, szUin)); - - debugLogA("Sending %s to %s", "ICQ_SIGNON_AUTH_REQUEST", "login server"); - - serverPacketInit(&packet, 14 + wUinLen); - packFNACHeader(&packet, ICQ_AUTHORIZATION_FAMILY, ICQ_SIGNON_AUTH_REQUEST, 0, 0); - packTLV(&packet, 0x0001, wUinLen, (LPBYTE)szUin); - sendServPacket(&packet); // request login digest - } - else { - sendClientAuth((char*)info->szAuthKey, info->wAuthKeyLen, FALSE); - debugLogA("Sent CLI_IDENT to %s", "login server"); - } - - info->isLoginServer = false; - if (info->cookieDataLen) { - SAFE_FREE((void**)&info->cookieData); - info->cookieDataLen = 0; - } - } - else { - if (info->cookieDataLen) { - wLocalSequence = generate_flap_sequence(); - - serverCookieInit(&packet, info->cookieData, info->cookieDataLen); - sendServPacket(&packet); - - debugLogA("Sent CLI_IDENT to %s", "communication server"); - - SAFE_FREE((void**)&info->cookieData); - info->cookieDataLen = 0; - } - else // We need a cookie to identify us to the communication server - debugLogA("Error: Connected to %s without a cookie!", "communication server"); - } -} diff --git a/protocols/IcqOscarJ/src/chan_02data.cpp b/protocols/IcqOscarJ/src/chan_02data.cpp deleted file mode 100644 index d330af877b..0000000000 --- a/protocols/IcqOscarJ/src/chan_02data.cpp +++ /dev/null @@ -1,200 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// Handle channel 2 (Data) packets -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -void CIcqProto::handleDataChannel(BYTE *pBuffer, size_t wBufferLength, serverthread_info *info) -{ - snac_header snacHeader = {0}; - - if (!unpackSnacHeader(&snacHeader, &pBuffer, &wBufferLength) || !snacHeader.bValid) - debugLogA("Error: Failed to parse SNAC header"); - else { - if (snacHeader.wFlags & 0x8000) - debugLogA(" Received SNAC(x%02X,x%02X), version %u", snacHeader.wFamily, snacHeader.wSubtype, snacHeader.wVersion); - else - debugLogA(" Received SNAC(x%02X,x%02X)", snacHeader.wFamily, snacHeader.wSubtype); - - switch (snacHeader.wFamily) { - - case ICQ_SERVICE_FAMILY: - handleServiceFam(pBuffer, wBufferLength, &snacHeader, info); - break; - - case ICQ_LOCATION_FAMILY: - handleLocationFam(pBuffer, wBufferLength, &snacHeader); - break; - - case ICQ_BUDDY_FAMILY: - handleBuddyFam(pBuffer, wBufferLength, &snacHeader, info); - break; - - case ICQ_MSG_FAMILY: - handleMsgFam(pBuffer, wBufferLength, &snacHeader); - break; - - case ICQ_BOS_FAMILY: - handleBosFam(pBuffer, wBufferLength, &snacHeader); - break; - - case ICQ_LOOKUP_FAMILY: - handleLookupFam(pBuffer, wBufferLength, &snacHeader); - break; - - case ICQ_STATS_FAMILY: - handleStatusFam(pBuffer, wBufferLength, &snacHeader); - break; - - case ICQ_LISTS_FAMILY: - handleServCListFam(pBuffer, wBufferLength, &snacHeader, info); - break; - - case ICQ_EXTENSIONS_FAMILY: - handleIcqExtensionsFam(pBuffer, wBufferLength, &snacHeader); - break; - - case ICQ_AUTHORIZATION_FAMILY: - handleAuthorizationFam(pBuffer, wBufferLength, &snacHeader, info); - break; - - default: - debugLogA("Ignoring SNAC(x%02X,x%02X) - FAMILYx%02X not implemented", snacHeader.wFamily, snacHeader.wSubtype, snacHeader.wFamily); - break; - } - } -} - - -int unpackSnacHeader(snac_header *pSnacHeader, BYTE **pBuffer, size_t *pwBufferLength) -{ - WORD wRef1, wRef2; - - // Check header - if (!pSnacHeader) - return 0; - - // 10 bytes is the minimum size of a header - if (*pwBufferLength < 10) { - // Buffer overflow - pSnacHeader->bValid = FALSE; - return 1; - } - - // Unpack all the standard data - unpackWord(pBuffer, &(pSnacHeader->wFamily)); - unpackWord(pBuffer, &(pSnacHeader->wSubtype)); - unpackWord(pBuffer, &(pSnacHeader->wFlags)); - unpackWord(pBuffer, &wRef1); // unpack reference id (sequence) - unpackWord(pBuffer, &wRef2); // command - pSnacHeader->dwRef = wRef1 | (wRef2 << 0x10); - - *pwBufferLength -= 10; - - // If flag bit 15 is set, we also have a version tag - // (...at least that is what I think it is) - if (pSnacHeader->wFlags & 0x8000) { - if (*pwBufferLength >= 2) { - WORD wExtraBytes = 0; - - unpackWord(pBuffer, &wExtraBytes); - *pwBufferLength -= 2; - - if (*pwBufferLength >= wExtraBytes) { - if (wExtraBytes == 6) { - *pBuffer += 4; // TLV type and length? - unpackWord(pBuffer, &(pSnacHeader->wVersion)); - *pwBufferLength -= wExtraBytes; - pSnacHeader->bValid = TRUE; - } - else if (wExtraBytes == 0x0E) { - *pBuffer += 8; // TLV(2) - unknown - *pBuffer += 4; - unpackWord(pBuffer, &(pSnacHeader->wVersion)); - *pwBufferLength -= wExtraBytes; - pSnacHeader->bValid = TRUE; - } - else { - *pBuffer += wExtraBytes; - *pwBufferLength -= wExtraBytes; - pSnacHeader->bValid = TRUE; - } - } - else // Buffer overflow - pSnacHeader->bValid = FALSE; - } - else // Buffer overflow - pSnacHeader->bValid = FALSE; - } - else pSnacHeader->bValid = TRUE; - - return 1; -} - - -void CIcqProto::LogFamilyError(WORD wFamily, WORD wError) -{ - char *msg; - - switch (wError) { - case 0x01: msg = "Invalid SNAC header"; break; - case 0x02: msg = "Server rate limit exceeded"; break; - case 0x03: msg = "Client rate limit exceeded"; break; - case 0x04: msg = "Recipient is not logged in"; break; - case 0x05: msg = "Requested service unavailable"; break; - case 0x06: msg = "Requested service not defined"; break; - case 0x07: msg = "You sent obsolete SNAC"; break; - case 0x08: msg = "Not supported by server"; break; - case 0x09: msg = "Not supported by client"; break; - case 0x0A: msg = "Refused by client"; break; - case 0x0B: msg = "Reply too big"; break; - case 0x0C: msg = "Responses lost"; break; - case 0x0D: msg = "Request denied"; break; - case 0x0E: msg = "Incorrect SNAC format"; break; - case 0x0F: msg = "Insufficient rights"; break; - case 0x10: msg = "In local permit/deny (recipient blocked)"; break; - case 0x11: msg = "Sender is too evil"; break; - case 0x12: msg = "Receiver is too evil"; break; - case 0x13: msg = "User temporarily unavailable"; break; - case 0x14: msg = "No match"; break; - case 0x15: msg = "List overflow"; break; - case 0x16: msg = "Request ambiguous"; break; - case 0x17: msg = "Server queue full"; break; - case 0x18: msg = "Not while on AOL"; break; - case 0x19: msg = "Query failed"; break; - case 0x1A: msg = "Timeout"; break; - case 0x1C: msg = "General failure"; break; - case 0x1D: msg = "Progress"; break; - case 0x1E: msg = "In free area"; break; - case 0x1F: msg = "Restricted by parental controls"; break; - case 0x20: msg = "Remote restricted by parental controls"; break; - default: msg = ""; break; - } - - debugLogA("SNAC(x%02X,x01) - Error(%u): %s", wFamily, wError, msg); -} diff --git a/protocols/IcqOscarJ/src/chan_03error.cpp b/protocols/IcqOscarJ/src/chan_03error.cpp deleted file mode 100644 index 5e0487b5a5..0000000000 --- a/protocols/IcqOscarJ/src/chan_03error.cpp +++ /dev/null @@ -1,31 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000,2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001,2002 Jon Keating, Richard Hughes -// Copyright © 2002,2003,2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004,2005 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -void CIcqProto::handleErrorChannel(unsigned char*, size_t) -{ - debugLogA("Ignoring server packet on ERROR channel"); -} diff --git a/protocols/IcqOscarJ/src/chan_04close.cpp b/protocols/IcqOscarJ/src/chan_04close.cpp deleted file mode 100644 index 8f4883d0a9..0000000000 --- a/protocols/IcqOscarJ/src/chan_04close.cpp +++ /dev/null @@ -1,279 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2009 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -void CIcqProto::handleCloseChannel(BYTE *buf, size_t datalen, serverthread_info *info) -{ - oscar_tlv_chain *chain = nullptr; - - // Parse server reply, prepare reconnection - if (!info->bLoggedIn && datalen && !info->isNewServerReady) - handleLoginReply(buf, datalen, info); - - if (info->isMigrating) - handleMigration(info); - - if ((!info->bLoggedIn || info->isMigrating) && info->isNewServerReady) { - if (!connectNewServer(info)) { // Connecting failed - if (info->isMigrating) - icq_LogUsingErrorCode(LOG_ERROR, GetLastError(), LPGEN("Unable to connect to migrated ICQ communication server")); - else - icq_LogUsingErrorCode(LOG_ERROR, GetLastError(), LPGEN("Unable to connect to ICQ communication server")); - - SetCurrentStatus(ID_STATUS_OFFLINE); - - info->isMigrating = false; - } - info->isNewServerReady = false; - return; - } - - if (chain = readIntoTLVChain(&buf, datalen, 0)) { - // TLV 9 errors (runtime errors?) - WORD wError = chain->getWord(0x09, 1); - if (wError) { - SetCurrentStatus(ID_STATUS_OFFLINE); - - handleRuntimeError(wError); - } - - disposeChain(&chain); - } - // Server closed connection on error, or sign off - NetLib_CloseConnection(&hServerConn, TRUE); -} - -void CIcqProto::handleLoginReply(BYTE *buf, size_t datalen, serverthread_info *info) -{ - oscar_tlv_chain *chain = nullptr; - - icq_sendCloseConnection(); // imitate icq5 behaviour - - if (!(chain = readIntoTLVChain(&buf, datalen, 0))) { - debugLogA("Error: Missing chain on close channel"); - NetLib_CloseConnection(&hServerConn, TRUE); - return; // Invalid data - } - - // TLV 8 errors (signon errors?) - WORD wError = chain->getWord(0x08, 1); - if (wError) { - handleSignonError(wError); - - // we return only if the server did not gave us cookie (possible to connect with soft error) - if (!chain->getLength(0x06, 1)) { - disposeChain(&chain); - icq_serverDisconnect(); - return; // Failure - } - } - - // We are in the login phase and no errors were reported. - // Extract communication server info. - info->newServer = chain->getString(0x05, 1); - info->newServerSSL = chain->getNumber(0x8E, 1); - info->cookieData = (BYTE*)chain->getString(0x06, 1); - info->cookieDataLen = chain->getLength(0x06, 1); - - // We dont need this anymore - disposeChain(&chain); - - if (!info->newServer || !info->cookieData) { - icq_LogMessage(LOG_FATAL, LPGEN("You could not sign on because the server returned invalid data. Try again.")); - - SAFE_FREE(&info->newServer); - SAFE_FREE((void**)&info->cookieData); - info->cookieDataLen = 0; - - SetCurrentStatus(ID_STATUS_OFFLINE); - NetLib_CloseConnection(&hServerConn, TRUE); - return; // Failure - } - - debugLogA("Authenticated."); - info->isNewServerReady = true; -} - -int CIcqProto::connectNewServer(serverthread_info *info) -{ - int res = 0; - - /* Get the ip and port */ - WORD wServerPort = info->wServerPort; // prepare default port - parseServerAddress(info->newServer, &wServerPort); - - NETLIBOPENCONNECTION nloc = { 0 }; - nloc.flags = 0; - nloc.szHost = info->newServer; - nloc.wPort = wServerPort; - - if (!m_bGatewayMode) { - NetLib_SafeCloseHandle(&info->hPacketRecver); - NetLib_CloseConnection(&hServerConn, TRUE); - - debugLogA("Closed connection to login server"); - - hServerConn = NetLib_OpenConnection(m_hNetlibUser, nullptr, &nloc); - if (hServerConn && info->newServerSSL) /* Start SSL session if requested */ - if (!Netlib_StartSsl(hServerConn, nullptr)) - NetLib_CloseConnection(&hServerConn, FALSE); - - if (hServerConn) { - /* Time to recreate the packet receiver */ - info->hPacketRecver = Netlib_CreatePacketReceiver(hServerConn, 0x2400); - if (!info->hPacketRecver) - debugLogA("Error: Failed to create packet receiver."); - else { // we need to reset receiving structs - info->bReinitRecver = true; - res = 1; - } - } - } - else { // TODO: We should really do some checks here - debugLogA("Walking in Gateway to %s", info->newServer); - // TODO: This REQUIRES more work (most probably some kind of mid-netlib module) - icq_httpGatewayWalkTo(hServerConn, &nloc); - res = 1; - } - if (!res) SAFE_FREE((void**)&info->cookieData); - - // Free allocated memory - // NOTE: "cookie" will get freed when we have connected to the communication server. - SAFE_FREE(&info->newServer); - - return res; -} - -void CIcqProto::handleMigration(serverthread_info *info) -{ - // Check the data that was saved when the migration was announced - debugLogA("Migrating to %s", info->newServer); - if (!info->newServer || !info->cookieData) { - icq_LogMessage(LOG_FATAL, LPGEN("You have been disconnected from the ICQ network because the current server shut down.")); - - SAFE_FREE(&info->newServer); - SAFE_FREE((void**)&info->cookieData); - info->isNewServerReady = info->isMigrating = false; - } -} - -void CIcqProto::handleSignonError(WORD wError) -{ - switch (wError) { - - case 0x01: // Unregistered uin - case 0x04: // Incorrect uin or password - case 0x05: // Mismatch uin or password - case 0x06: // Internal Client error (bad input to authorizer) - case 0x07: // Invalid account - ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, nullptr, LOGINERR_WRONGPASSWORD); - memset(m_szPassword, 0, sizeof(m_szPassword)); - icq_LogFatalParam(LPGEN("Connection failed.\nYour ICQ number or password was rejected (%d)."), wError); - break; - - case 0x02: // Service temporarily unavailable - case 0x0D: // Bad database status - case 0x10: // Service temporarily offline - case 0x12: // Database send error - case 0x14: // Reservation map error - case 0x15: // Reservation link error - case 0x1A: // Reservation timeout - ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, nullptr, LOGINERR_NOSERVER); - icq_LogFatalParam(LPGEN("Connection failed.\nThe server is temporarily unavailable (%d)."), wError); - break; - - case 0x16: // The users num connected from this IP has reached the maximum - case 0x17: // The users num connected from this IP has reached the maximum (reserved) - icq_LogFatalParam(LPGEN("Connection failed.\nServer has too many connections from your IP (%d)."), wError); - break; - - case 0x18: // Reservation rate limit exceeded - case 0x1D: // Rate limit exceeded - ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, nullptr, LOGINERR_NOSERVER); - icq_LogFatalParam(LPGEN("Connection failed.\nYou have connected too quickly,\nplease wait and retry 10 to 20 minutes later (%d)."), wError); - break; - - case 0x1B: // You are using an older version of ICQ. Upgrade required - ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, nullptr, LOGINERR_WRONGPROTOCOL); - icq_LogMessage(LOG_FATAL, LPGEN("Connection failed.\nThe server did not accept this client version.")); - break; - - case 0x1C: // You are using an older version of ICQ. Upgrade recommended - icq_LogMessage(LOG_WARNING, LPGEN("The server sent warning, this version is getting old.\nTry to look for a new one.")); - break; - - case 0x1E: // Can't register on the ICQ network - icq_LogMessage(LOG_FATAL, LPGEN("Connection failed.\nYou were rejected by the server for an unknown reason.\nThis can happen if the UIN is already connected.")); - break; - - case 0x0C: // Invalid database fields, MD5 login not supported - icq_LogMessage(LOG_FATAL, LPGEN("Connection failed.\nSecure (MD5) login is not supported on this account.")); - break; - - case 0: // No error - break; - - case 0x08: // Deleted account - case 0x09: // Expired account - case 0x0A: // No access to database - case 0x0B: // No access to resolver - case 0x0E: // Bad resolver status - case 0x0F: // Internal error - case 0x11: // Suspended account - case 0x13: // Database link error - case 0x19: // User too heavily warned - case 0x1F: // Token server timeout - case 0x20: // Invalid SecureID number - case 0x21: // MC error - case 0x22: // Age restriction - case 0x23: // RequireRevalidation - case 0x24: // Link rule rejected - case 0x25: // Missing information or bad SNAC format - case 0x26: // Link broken - case 0x27: // Invalid client IP - case 0x28: // Partner rejected - case 0x29: // SecureID missing - case 0x2A: // Blocked account | Bump user - - default: - icq_LogFatalParam(LPGEN("Connection failed.\nUnknown error during sign on: 0x%02x"), wError); - break; - } -} - -void CIcqProto::handleRuntimeError(WORD wError) -{ - switch (wError) { - case 0x01: - ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, nullptr, LOGINERR_OTHERLOCATION); - icq_LogMessage(LOG_FATAL, LPGEN("You have been disconnected from the ICQ network because you logged on from another location using the same ICQ number.")); - break; - - default: - icq_LogFatalParam(LPGEN("Unknown runtime error: 0x%02x"), wError); - break; - } -} diff --git a/protocols/IcqOscarJ/src/chan_05ping.cpp b/protocols/IcqOscarJ/src/chan_05ping.cpp deleted file mode 100644 index 05cbc27d74..0000000000 --- a/protocols/IcqOscarJ/src/chan_05ping.cpp +++ /dev/null @@ -1,59 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2009 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -void CIcqProto::handlePingChannel(BYTE*, size_t) -{ - debugLogA("Warning: Ignoring server packet on PING channel"); -} - -void CIcqProto::StartKeepAlive(serverthread_info *info) -{ - if (getByte("KeepAlive", DEFAULT_KEEPALIVE_ENABLED)) - info->tmPing = time(0) + KEEPALIVE_INTERVAL; - else - info->tmPing = -1; -} - -void CIcqProto::StopKeepAlive(serverthread_info *info) -{ - info->tmPing = -1; -} - -void CIcqProto::CheckKeepAlive(serverthread_info *info) -{ - if (info->tmPing == -1) - return; - - if (time(0) >= info->tmPing) { - // Send a keep alive packet to server - icq_packet packet = { 0 }; - write_flap(&packet, ICQ_PING_CHAN); - sendServPacket(&packet); - - StartKeepAlive(info); - } -} diff --git a/protocols/IcqOscarJ/src/changeinfo.h b/protocols/IcqOscarJ/src/changeinfo.h deleted file mode 100644 index ef4de019a6..0000000000 --- a/protocols/IcqOscarJ/src/changeinfo.h +++ /dev/null @@ -1,121 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2001-2004 Richard Hughes, Martin Öberg -// Copyright © 2004-2010 Joe Kucera, Bio -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// ChangeInfo Plugin stuff -// ----------------------------------------------------------------------------- - -#ifndef __CHANGEINFO_H -#define __CHANGEINFO_H - - -#ifndef AW_SLIDE -#define SPI_GETCOMBOBOXANIMATION 0x1004 -#define AW_SLIDE 0x40000 -#define AW_ACTIVATE 0x20000 -#define AW_VER_POSITIVE 0x4 -#define UDM_SETPOS32 (WM_USER+113) -#define UDM_GETPOS32 (WM_USER+114) -#endif - - -#define LI_DIVIDER 0 -#define LI_STRING 1 -#define LI_LIST 2 -#define LI_LONGSTRING 3 -#define LI_NUMBER 4 -#define LIM_TYPE 0x0000FFFF -#define LIF_ZEROISVALID 0x80000000 -#define LIF_SIGNED 0x40000000 -#define LIF_PASSWORD 0x20000000 -#define LIF_CHANGEONLY 0x10000000 - -struct SettingItem -{ - const char *szDescription; - unsigned displayType; //LI_ constant - int dbType; //DBVT_ constant - const char *szDbSetting; - const void *pList; -}; - -struct SettingItemData -{ - LPARAM value; - int changed; -}; - -// contants.c -extern const SettingItem setting[]; -extern const int settingCount; - -//dlgproc.c -struct ChangeInfoData : public MZeroedObject -{ - HWND hwndDlg; - CIcqProto *ppro; - HFONT hListFont; - HWND hwndList; - int editTopIndex; - int iEditItem; - char Password[PASSWORDMAXLEN + 1]; - - SettingItemData *settingData; - - HANDLE hAckHook; - HANDLE hUpload[2]; - - ChangeInfoData() { settingData = (SettingItemData*)SAFE_MALLOC(sizeof(SettingItemData) * settingCount); hAckHook = nullptr; hUpload[0] = nullptr; hUpload[1] = nullptr; } - ~ChangeInfoData() { SAFE_FREE((void**)&settingData); } - - char* GetItemSettingText(int i, char *buf, size_t buf_size); - void PaintItemSetting(HDC hdc, RECT *rc, int i, UINT itemState); - - //db.cpp - void LoadSettingsFromDb(int keepChanged); - void FreeStoredDbSettings(void); - int ChangesMade(void); - void ClearChangeFlags(void); - int SaveSettingsToDb(void); - - //upload.cpp - int UploadSettings(void); - - //editstring.cpp - void BeginStringEdit(int iItem, RECT *rc, int i, WORD wVKey); - void EndStringEdit(int save); - //editlist.cpp - void BeginListEdit(int iItem, RECT *rc, int iSetting, WORD wVKey); - void EndListEdit(int save); -}; - -INT_PTR CALLBACK ChangeInfoDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); - -//editstring.c -int IsStringEditWindow(HWND hwnd); -char* BinaryToEscapes(char *str); - -//editlist.c -int IsListEditWindow(HWND hwnd); - -#endif /* __CHANGEINFO_H */ diff --git a/protocols/IcqOscarJ/src/channels.h b/protocols/IcqOscarJ/src/channels.h deleted file mode 100644 index 6bce28b5b8..0000000000 --- a/protocols/IcqOscarJ/src/channels.h +++ /dev/null @@ -1,45 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// Header for FLAP Channel packet handlers -// ----------------------------------------------------------------------------- - -#ifndef __CHANNELS_H -#define __CHANNELS_H - -struct snac_header -{ - BOOL bValid; - WORD wFamily; - WORD wSubtype; - WORD wFlags; - DWORD dwRef; - WORD wVersion; -}; - -int unpackSnacHeader(snac_header *pSnacHeader, BYTE **pBuffer, size_t *pwBufferLength); - -#endif /* __CHANNELS_H */ diff --git a/protocols/IcqOscarJ/src/constants.cpp b/protocols/IcqOscarJ/src/constants.cpp deleted file mode 100644 index d07e8352f5..0000000000 --- a/protocols/IcqOscarJ/src/constants.cpp +++ /dev/null @@ -1,131 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2001-2004 Richard Hughes, Martin Öberg -// Copyright © 2004-2009 Joe Kucera, Bio -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// ChangeInfo Plugin stuff -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -static FieldNamesItem months[] = { - { 1, LPGEN("January") }, - { 2, LPGEN("February") }, - { 3, LPGEN("March") }, - { 4, LPGEN("April") }, - { 5, LPGEN("May") }, - { 6, LPGEN("June") }, - { 7, LPGEN("July") }, - { 8, LPGEN("August") }, - { 9, LPGEN("September") }, - { 10, LPGEN("October") }, - { 11, LPGEN("November") }, - { 12, LPGEN("December") }, - { 0, nullptr } -}; - -const int ageRange[] = { 13, 0x7FFF }; // 14, 130 -const int yearRange[] = { 1753, 0x7FFF }; // 1880, 2000 -const int dayRange[] = { 1, 31 }; - -const SettingItem setting[] = -{ - // personal - { LPGEN("Personal"), LI_DIVIDER }, - { LPGEN("Nickname"), LI_STRING, DBVT_UTF8, "Nick" }, - { LPGEN("First name"), LI_STRING, DBVT_UTF8, "FirstName" }, - { LPGEN("Last name"), LI_STRING, DBVT_UTF8, "LastName" }, - { LPGEN("Gender"), LI_LIST, DBVT_BYTE, "Gender", genderField }, - { LPGEN("About"), LI_LONGSTRING, DBVT_UTF8, "About" }, - - // password - { LPGEN("Password"), LI_DIVIDER }, - { LPGEN("Password"), LI_STRING | LIF_PASSWORD, DBVT_UTF8, "Password" }, - - // contact - { LPGEN("Contact"), LI_DIVIDER }, - { LPGEN("Primary e-mail"), LI_STRING, DBVT_UTF8, "e-mail0" }, - { LPGEN("Secondary e-mail"), LI_STRING, DBVT_UTF8, "e-mail1" }, - { LPGEN("Tertiary e-mail"), LI_STRING, DBVT_UTF8, "e-mail2" }, - { LPGEN("Homepage"), LI_STRING, DBVT_UTF8, "Homepage" }, - { LPGEN("Street"), LI_STRING, DBVT_UTF8, "Street" }, - { LPGEN("City"), LI_STRING, DBVT_UTF8, "City" }, - { LPGEN("State"), LI_STRING, DBVT_UTF8, "State" }, - { LPGEN("ZIP/postcode"), LI_STRING, DBVT_UTF8, "ZIP" }, - { LPGEN("Country"), LI_LIST, DBVT_WORD, "Country", countryField }, - { LPGEN("Phone number"), LI_STRING, DBVT_UTF8, "Phone" }, - { LPGEN("Fax number"), LI_STRING, DBVT_UTF8, "Fax" }, - { LPGEN("Cellular number"), LI_STRING, DBVT_UTF8, "Cellular" }, - - // more - { LPGEN("Personal Detail"), LI_DIVIDER }, - { LPGEN("Timezone"), LI_LIST | LIF_ZEROISVALID | LIF_SIGNED, DBVT_BYTE, "Timezone", timezonesField }, - { LPGEN("Year of birth"), LI_NUMBER, DBVT_WORD, "BirthYear", yearRange }, - { LPGEN("Month of birth"), LI_LIST, DBVT_BYTE, "BirthMonth", months }, - { LPGEN("Day of birth"), LI_NUMBER, DBVT_BYTE, "BirthDay", dayRange }, - { LPGEN("Marital Status"), LI_LIST, DBVT_BYTE, "MaritalStatus", maritalField }, - { LPGEN("Spoken language 1"), LI_LIST, DBVT_BYTE, "Language1", languageField }, - { LPGEN("Spoken language 2"), LI_LIST, DBVT_BYTE, "Language2", languageField }, - { LPGEN("Spoken language 3"), LI_LIST, DBVT_BYTE, "Language3", languageField }, - - // more - { LPGEN("Originally from"), LI_DIVIDER }, - { LPGEN("Street"), LI_STRING, DBVT_UTF8, "OriginStreet" }, - { LPGEN("City"), LI_STRING, DBVT_UTF8, "OriginCity" }, - { LPGEN("State"), LI_STRING, DBVT_UTF8, "OriginState" }, - { LPGEN("Country"), LI_LIST, DBVT_WORD, "OriginCountry", countryField }, - - // study - { LPGEN("Education"), LI_DIVIDER }, - { LPGEN("Level"), LI_LIST, DBVT_WORD, "StudyLevel", studyLevelField }, - { LPGEN("Institute"), LI_STRING, DBVT_UTF8, "StudyInstitute" }, - { LPGEN("Degree"), LI_STRING, DBVT_UTF8, "StudyDegree" }, - { LPGEN("Graduation Year"), LI_NUMBER, DBVT_WORD, "StudyYear", yearRange }, - - // work - { LPGEN("Work"), LI_DIVIDER }, - { LPGEN("Company name"), LI_STRING, DBVT_UTF8, "Company" }, - { LPGEN("Company homepage"), LI_STRING, DBVT_UTF8, "CompanyHomepage" }, - { LPGEN("Company street"), LI_STRING, DBVT_UTF8, "CompanyStreet" }, - { LPGEN("Company city"), LI_STRING, DBVT_UTF8, "CompanyCity" }, - { LPGEN("Company state"), LI_STRING, DBVT_UTF8, "CompanyState" }, - { LPGEN("Company phone"), LI_STRING, DBVT_UTF8, "CompanyPhone" }, - { LPGEN("Company fax"), LI_STRING, DBVT_UTF8, "CompanyFax" }, - { LPGEN("Company ZIP/postcode"), LI_STRING, DBVT_UTF8, "CompanyZIP" }, - { LPGEN("Company country"), LI_LIST, DBVT_WORD, "CompanyCountry", countryField }, - { LPGEN("Company department"), LI_STRING, DBVT_UTF8, "CompanyDepartment" }, - { LPGEN("Company position"), LI_STRING, DBVT_UTF8, "CompanyPosition" }, - { LPGEN("Company industry"), LI_LIST, DBVT_WORD, "CompanyIndustry", industryField }, - - //interests - { LPGEN("Personal Interests"), LI_DIVIDER }, - { LPGEN("Interest category 1"), LI_LIST, DBVT_WORD, "Interest0Cat", interestsField }, - { LPGEN("Interest areas 1"), LI_STRING, DBVT_UTF8, "Interest0Text" }, - { LPGEN("Interest category 2"), LI_LIST, DBVT_WORD, "Interest1Cat", interestsField }, - { LPGEN("Interest areas 2"), LI_STRING, DBVT_UTF8, "Interest1Text" }, - { LPGEN("Interest category 3"), LI_LIST, DBVT_WORD, "Interest2Cat", interestsField }, - { LPGEN("Interest areas 3"), LI_STRING, DBVT_UTF8, "Interest2Text" }, - { LPGEN("Interest category 4"), LI_LIST, DBVT_WORD, "Interest3Cat", interestsField }, - { LPGEN("Interest areas 4"), LI_STRING, DBVT_UTF8, "Interest3Text" }, -}; - -const int settingCount = _countof(setting); diff --git a/protocols/IcqOscarJ/src/cookies.cpp b/protocols/IcqOscarJ/src/cookies.cpp deleted file mode 100644 index a9d09534c7..0000000000 --- a/protocols/IcqOscarJ/src/cookies.cpp +++ /dev/null @@ -1,254 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// Handles packet & message cookies -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -void CIcqProto::RemoveExpiredCookies() -{ - time_t tNow = time(0); - - auto T = cookies.rev_iter(); - for (auto &it : T) - if (it->dwTime + COOKIE_TIMEOUT < tNow) - cookies.remove(T.indexOf(&it)); -} - -// Generate and allocate cookie -DWORD CIcqProto::AllocateCookie(BYTE bType, WORD wIdent, MCONTACT hContact, void *pvExtra) -{ - mir_cslock l(cookieMutex); - - DWORD dwThisSeq = wCookieSeq++; - dwThisSeq &= 0x7FFF; - dwThisSeq |= wIdent << 0x10; - - icq_cookie_info *p = new icq_cookie_info(); - p->bType = bType; - p->dwCookie = dwThisSeq; - p->hContact = hContact; - p->pvExtra = pvExtra; - p->dwTime = time(0); - cookies.insert(p); - - return dwThisSeq; -} - -DWORD CIcqProto::GenerateCookie(WORD wIdent) -{ - mir_cslock l(cookieMutex); - - DWORD dwThisSeq = wCookieSeq++; - dwThisSeq &= 0x7FFF; - dwThisSeq |= wIdent << 0x10; - return dwThisSeq; -} - -int CIcqProto::GetCookieType(DWORD dwCookie) -{ - mir_cslock l(cookieMutex); - - int i = cookies.getIndex((icq_cookie_info*)&dwCookie); - if (i != -1) - i = cookies[i].bType; - - return i; -} - -int CIcqProto::FindCookie(DWORD dwCookie, MCONTACT *phContact, void **ppvExtra) -{ - mir_cslock l(cookieMutex); - - int i = cookies.getIndex((icq_cookie_info*)&dwCookie); - if (i != -1) { - if (phContact) - *phContact = cookies[i].hContact; - if (ppvExtra) - *ppvExtra = cookies[i].pvExtra; - - // Cookie found - return 1; - } - - return 0; -} - -int CIcqProto::FindCookieByData(void *pvExtra, DWORD *pdwCookie, MCONTACT *phContact) -{ - mir_cslock l(cookieMutex); - - for (auto &it : cookies) { - if (pvExtra == it->pvExtra) { - if (phContact) - *phContact = it->hContact; - if (pdwCookie) - *pdwCookie = it->dwCookie; - - // Cookie found - return 1; - } - } - - return 0; -} - -int CIcqProto::FindCookieByType(BYTE bType, DWORD *pdwCookie, MCONTACT *phContact, void **ppvExtra) -{ - mir_cslock l(cookieMutex); - - for (auto &it : cookies) { - if (bType == it->bType) { - if (pdwCookie) - *pdwCookie = it->dwCookie; - if (phContact) - *phContact = it->hContact; - if (ppvExtra) - *ppvExtra = it->pvExtra; - - // Cookie found - return 1; - } - } - - return 0; -} - -int CIcqProto::FindMessageCookie(DWORD dwMsgID1, DWORD dwMsgID2, DWORD *pdwCookie, MCONTACT *phContact, cookie_message_data **ppvExtra) -{ - mir_cslock l(cookieMutex); - - for (auto &it : cookies) { - if (it->bType == CKT_MESSAGE || it->bType == CKT_FILE || it->bType == CKT_REVERSEDIRECT) { - // message cookie found - cookie_message_data *pCookie = (cookie_message_data*)it->pvExtra; - - if (pCookie->dwMsgID1 == dwMsgID1 && pCookie->dwMsgID2 == dwMsgID2) { - if (phContact) - *phContact = it->hContact; - if (pdwCookie) - *pdwCookie = it->dwCookie; - if (ppvExtra) - *ppvExtra = pCookie; - - // Cookie found - return 1; - } - } - } - - return 0; -} - -void CIcqProto::FreeCookie(DWORD dwCookie) -{ - mir_cslock l(cookieMutex); - - int i = cookies.getIndex((icq_cookie_info*)&dwCookie); - if (i != -1) // Cookie found, remove from list - cookies.remove(i); - - RemoveExpiredCookies(); -} - -void CIcqProto::FreeCookieByData(BYTE bType, void *pvExtra) -{ - mir_cslock l(cookieMutex); - - for (auto &it : cookies) { - if (bType == it->bType && pvExtra == it->pvExtra) { - // Cookie found, remove from list - cookies.removeItem(&it); - break; - } - } - - RemoveExpiredCookies(); -} - -void CIcqProto::ReleaseCookie(DWORD dwCookie) -{ - mir_cslock l(cookieMutex); - - int i = cookies.getIndex((icq_cookie_info*)&dwCookie); - if (i != -1) { // Cookie found, remove from list - SAFE_FREE((void**)&cookies[i].pvExtra); - cookies.remove(i); - } - - RemoveExpiredCookies(); -} - -void CIcqProto::InitMessageCookie(cookie_message_data *pCookie) -{ - DWORD dwMsgID1; - DWORD dwMsgID2; - - do { - // ensure that message ids are unique - dwMsgID1 = time(0); - dwMsgID2 = RandRange(0, 0x0FFFF); - } while (FindMessageCookie(dwMsgID1, dwMsgID2, nullptr, nullptr, nullptr)); - - if (pCookie) { - pCookie->dwMsgID1 = dwMsgID1; - pCookie->dwMsgID2 = dwMsgID2; - } -} - -cookie_message_data* CIcqProto::CreateMessageCookie(WORD bMsgType, BYTE bAckType) -{ - cookie_message_data *pCookie = (cookie_message_data*)SAFE_MALLOC(sizeof(cookie_message_data)); - if (pCookie) { - pCookie->bMessageType = bMsgType; - pCookie->nAckType = bAckType; - - InitMessageCookie(pCookie); - } - return pCookie; -} - -cookie_message_data* CIcqProto::CreateMessageCookieData(BYTE bMsgType, MCONTACT hContact, DWORD dwUin, int bUseSrvRelay) -{ - BYTE bAckType; - WORD wStatus = getContactStatus(hContact); - - if (!getByte(hContact, "SlowSend", getByte("SlowSend", DEFAULT_SLOWSEND)) || (!dwUin && wStatus == ID_STATUS_OFFLINE)) - bAckType = ACKTYPE_NONE; - else if (bUseSrvRelay) - bAckType = ACKTYPE_CLIENT; - else - bAckType = ACKTYPE_SERVER; - - cookie_message_data* pCookieData = CreateMessageCookie(bMsgType, bAckType); - - // set flag for offline messages - to allow proper error handling - if (wStatus == ID_STATUS_OFFLINE || wStatus == ID_STATUS_INVISIBLE) - pCookieData->isOffline = TRUE; - - return pCookieData; -} diff --git a/protocols/IcqOscarJ/src/cookies.h b/protocols/IcqOscarJ/src/cookies.h deleted file mode 100644 index ad8c1bb306..0000000000 --- a/protocols/IcqOscarJ/src/cookies.h +++ /dev/null @@ -1,136 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- - -#ifndef __COOKIES_H -#define __COOKIES_H - -#define CKT_MESSAGE 0x01 -#define CKT_FILE 0x02 -#define CKT_SEARCH 0x04 -#define CKT_SERVERLIST 0x08 -#define CKT_SERVICEREQUEST 0x0A -#define CKT_REVERSEDIRECT 0x0C -#define CKT_FAMILYSPECIAL 0x10 -#define CKT_OFFLINEMESSAGE 0x12 -#define CKT_DIRECTORY_QUERY 0x18 -#define CKT_DIRECTORY_UPDATE 0x19 -#define CKT_AVATAR 0x20 - -struct CIcqProto; - -/* Basic structure used to hold operation cookies list */ - -struct icq_cookie_info : public MZeroedObject -{ - DWORD dwCookie; - MCONTACT hContact; - void *pvExtra; - time_t dwTime; - BYTE bType; -}; - -/* Specific structures to hold request specific data - pvExtra */ - -struct cookie_family_request -{ - WORD wFamily; - void (CIcqProto::*familyHandler)(HNETLIBCONN hConn, char* cookie, size_t cookieLen); -}; - -struct cookie_offline_messages -{ - int nMessages; - int nMissed; -}; - -#define ACKTYPE_NONE 0 -#define ACKTYPE_SERVER 1 -#define ACKTYPE_CLIENT 2 - -struct cookie_message_data -{ - DWORD dwMsgID1; - DWORD dwMsgID2; - WORD bMessageType; - BYTE nAckType; - BYTE isOffline; -}; - -#define REQUESTTYPE_OWNER 0 -#define REQUESTTYPE_USERAUTO 1 -#define REQUESTTYPE_USERMINIMAL 2 -#define REQUESTTYPE_USERDETAILED 3 -#define REQUESTTYPE_PROFILE 4 - -struct cookie_fam15_data -{ - BYTE bRequestType; -}; - -#define SEARCHTYPE_UID 0 -#define SEARCHTYPE_EMAIL 1 -#define SEARCHTYPE_NAMES 2 -#define SEARCHTYPE_DETAILS 4 - -struct cookie_search -{ - BYTE bSearchType; - char* szObject; - DWORD dwMainId; - DWORD dwStatus; -}; - -struct cookie_avatar -{ - DWORD dwUin; - MCONTACT hContact; - size_t hashlen; - BYTE *hash; - size_t cbData; - wchar_t *szFile; -}; - -struct cookie_reverse_connect : public cookie_message_data -{ - MCONTACT hContact; - DWORD dwUin; - int type; - void *ft; -}; - -#define DIRECTORYREQUEST_INFOUSER 0x01 -#define DIRECTORYREQUEST_INFOOWNER 0x02 -#define DIRECTORYREQUEST_INFOMULTI 0x03 -#define DIRECTORYREQUEST_SEARCH 0x08 -#define DIRECTORYREQUEST_UPDATEOWNER 0x10 -#define DIRECTORYREQUEST_UPDATENOTE 0x11 -#define DIRECTORYREQUEST_UPDATEPRIVACY 0x12 - -struct cookie_directory_data -{ - BYTE bRequestType; -}; - -#endif /* __COOKIES_H */ diff --git a/protocols/IcqOscarJ/src/db.cpp b/protocols/IcqOscarJ/src/db.cpp deleted file mode 100644 index f07b2b0594..0000000000 --- a/protocols/IcqOscarJ/src/db.cpp +++ /dev/null @@ -1,153 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2001-2004 Richard Hughes, Martin Öberg -// Copyright © 2004-2009 Joe Kucera, Bio -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// ChangeInfo Plugin stuff -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -void ChangeInfoData::LoadSettingsFromDb(int keepChanged) -{ - for (int i = 0; i < settingCount; i++) { - const SettingItem &si = setting[i]; - if (si.displayType == LI_DIVIDER) - continue; - - SettingItemData &sid = settingData[i]; - if (keepChanged && sid.changed) - continue; - - if (si.dbType == DBVT_ASCIIZ || si.dbType == DBVT_UTF8) - SAFE_FREE((void**)(char**)&sid.value); - else if (!keepChanged) - sid.value = 0; - - sid.changed = 0; - - if (si.displayType & LIF_PASSWORD) - continue; - - DBVARIANT dbv = { DBVT_DELETED }; - if (!ppro->getSetting(NULL, si.szDbSetting, &dbv)) { - switch (dbv.type) { - case DBVT_ASCIIZ: - sid.value = (LPARAM)ppro->getSettingStringUtf(NULL, si.szDbSetting, nullptr); - break; - - case DBVT_UTF8: - sid.value = (LPARAM)null_strdup(dbv.pszVal); - break; - - case DBVT_WORD: - if (si.displayType & LIF_SIGNED) - sid.value = dbv.sVal; - else - sid.value = dbv.wVal; - break; - - case DBVT_BYTE: - if (si.displayType & LIF_SIGNED) - sid.value = dbv.cVal; - else - sid.value = dbv.bVal; - break; - -#ifdef _DEBUG - default: - MessageBoxA(nullptr, "That's not supposed to happen either", "Huh?", MB_OK); - break; -#endif - } - db_free(&dbv); - } - - char buf[MAX_PATH]; - wchar_t tbuf[MAX_PATH]; - - if (make_unicode_string_static(GetItemSettingText(i, buf, _countof(buf)), tbuf, _countof(tbuf))) - ListView_SetItemText(hwndList, i, 1, tbuf); - } -} - -void ChangeInfoData::FreeStoredDbSettings(void) -{ - for (int i = 0; i < settingCount; i++) - if (setting[i].dbType == DBVT_ASCIIZ || setting[i].dbType == DBVT_UTF8) - SAFE_FREE((void**)&settingData[i].value); -} - -int ChangeInfoData::ChangesMade(void) -{ - for (int i = 0; i < settingCount; i++) - if (settingData[i].changed) - return 1; - return 0; -} - -void ChangeInfoData::ClearChangeFlags(void) -{ - for (int i = 0; i < settingCount; i++) - settingData[i].changed = 0; -} - -int ChangeInfoData::SaveSettingsToDb() -{ - int ret = 1; - - for (int i = 0; i < settingCount; i++) { - SettingItemData &sid = settingData[i]; - if (!sid.changed) - continue; - - const SettingItem &si = setting[i]; - if (!(si.displayType & LIF_ZEROISVALID) && sid.value == 0) { - ppro->delSetting(si.szDbSetting); - continue; - } - switch (si.dbType) { - case DBVT_ASCIIZ: - if (*(char*)sid.value) - db_set_utf(NULL, ppro->m_szModuleName, si.szDbSetting, (char*)sid.value); - else - ppro->delSetting(si.szDbSetting); - break; - - case DBVT_UTF8: - if (*(char*)sid.value) - db_set_utf(NULL, ppro->m_szModuleName, si.szDbSetting, (char*)sid.value); - else - ppro->delSetting(si.szDbSetting); - break; - - case DBVT_WORD: - ppro->setWord(si.szDbSetting, (WORD)sid.value); - break; - - case DBVT_BYTE: - ppro->setByte(si.szDbSetting, (BYTE)sid.value); - break; - } - } - return ret; -} diff --git a/protocols/IcqOscarJ/src/directpackets.cpp b/protocols/IcqOscarJ/src/directpackets.cpp deleted file mode 100644 index a7f32e7248..0000000000 --- a/protocols/IcqOscarJ/src/directpackets.cpp +++ /dev/null @@ -1,273 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -void EncryptDirectPacket(directconnect* dc, icq_packet* p); - -void packEmptyMsg(icq_packet *packet); - -static void packDirectMsgHeader(icq_packet* packet, size_t wDataLen, WORD wCommand, DWORD dwCookie, BYTE bMsgType, BYTE bMsgFlags, WORD wX1, WORD wX2) -{ - directPacketInit(packet, 29 + wDataLen); - packByte(packet, 2); /* channel */ - packLEDWord(packet, 0); /* space for crypto */ - packLEWord(packet, wCommand); - packLEWord(packet, 14); /* unknown */ - packLEWord(packet, (WORD)dwCookie); - packLEDWord(packet, 0); /* unknown */ - packLEDWord(packet, 0); /* unknown */ - packLEDWord(packet, 0); /* unknown */ - packByte(packet, bMsgType); - packByte(packet, bMsgFlags); - packLEWord(packet, wX1); /* unknown. Is 1 for getawaymsg, 0 otherwise */ - packLEWord(packet, wX2); // this is probably priority -} - - -void CIcqProto::icq_sendDirectMsgAck(directconnect* dc, WORD wCookie, BYTE bMsgType, BYTE bMsgFlags, char* szCap) -{ - icq_packet packet; - packDirectMsgHeader(&packet, bMsgType == MTYPE_PLAIN ? (szCap ? 53 : 11) : 3, DIRECT_ACK, wCookie, bMsgType, bMsgFlags, 0, 0); - packEmptyMsg(&packet); /* empty message */ - - if (bMsgType == MTYPE_PLAIN) { - packMsgColorInfo(&packet); - - if (szCap) { - packLEDWord(&packet, 0x26); /* CLSID length */ - packBuffer(&packet, (LPBYTE)szCap, 0x26); /* GUID */ - } - } - EncryptDirectPacket(dc, &packet); - sendDirectPacket(dc, &packet); - - NetLog_Direct("Sent acknowledgement thru direct connection"); -} - - -DWORD CIcqProto::icq_sendGetAwayMsgDirect(MCONTACT hContact, int type) -{ - if (getWord(hContact, "Version", 0) >= 9) - return 0; // v9 DC protocol does not support this message - - cookie_message_data *pCookieData = CreateMessageCookie(MTYPE_AUTOAWAY, (BYTE)type); - DWORD dwCookie = AllocateCookie(CKT_MESSAGE, 0, hContact, (void*)pCookieData); - - icq_packet packet; - packDirectMsgHeader(&packet, 3, DIRECT_MESSAGE, dwCookie, (BYTE)type, 3, 1, 0); - packEmptyMsg(&packet); // message - - return (SendDirectMessage(hContact, &packet)) ? dwCookie : 0; -} - - -void CIcqProto::icq_sendAwayMsgReplyDirect(directconnect* dc, WORD wCookie, BYTE msgType, const char** szMsg) -{ - if (validateStatusMessageRequest(dc->hContact, msgType)) { - NotifyEventHooks(m_modeMsgsEvent, (WPARAM)msgType, (LPARAM)dc->dwRemoteUin); - - mir_cslock l(m_modeMsgsMutex); - - if (szMsg && *szMsg) { - // prepare Ansi message - only Ansi supported - size_t wMsgLen = mir_strlen(*szMsg) + 1; - char *szAnsiMsg = (char*)_alloca(wMsgLen); - - utf8_decode_static(*szMsg, szAnsiMsg, wMsgLen); - wMsgLen = mir_strlen(szAnsiMsg); - - icq_packet packet; - packDirectMsgHeader(&packet, 3 + wMsgLen, DIRECT_ACK, wCookie, msgType, 3, 0, 0); - packLEWord(&packet, WORD(wMsgLen + 1)); - packBuffer(&packet, (LPBYTE)szAnsiMsg, wMsgLen + 1); - EncryptDirectPacket(dc, &packet); - - sendDirectPacket(dc, &packet); - } - } -} - - -void CIcqProto::icq_sendFileAcceptDirect(MCONTACT hContact, filetransfer* ft) -{ - // v7 packet - icq_packet packet; - packDirectMsgHeader(&packet, 18, DIRECT_ACK, ft->dwCookie, MTYPE_FILEREQ, 0, 0, 0); - packLEWord(&packet, 1); // description - packByte(&packet, 0); - packWord(&packet, wListenPort); - packLEWord(&packet, 0); - packLEWord(&packet, 1); // filename - packByte(&packet, 0); // TODO: really send filename - packLEDWord(&packet, ft->dwTotalSize); // file size - packLEDWord(&packet, wListenPort); // FIXME: ideally we want to open a new port for this - - SendDirectMessage(hContact, &packet); - - NetLog_Direct("Sent file accept direct, port %u", wListenPort); -} - - -void CIcqProto::icq_sendFileDenyDirect(MCONTACT hContact, filetransfer *ft, const char *szReason) -{ - // v7 packet - icq_packet packet; - char *szReasonAnsi = nullptr; - if (!utf8_decode(szReason, &szReasonAnsi)) - szReasonAnsi = _strdup(szReason); // Legacy fix - size_t cbReasonAnsi = mir_strlen(szReasonAnsi); - - packDirectMsgHeader(&packet, 18 + cbReasonAnsi, DIRECT_ACK, ft->dwCookie, MTYPE_FILEREQ, 0, 1, 0); - packLEWord(&packet, WORD(1 + cbReasonAnsi)); // description - if (szReasonAnsi) - packBuffer(&packet, (LPBYTE)szReasonAnsi, cbReasonAnsi); - packByte(&packet, 0); - packWord(&packet, 0); - packLEWord(&packet, 0); - packLEWord(&packet, 1); // filename - packByte(&packet, 0); // TODO: really send filename - packLEDWord(&packet, 0); // file size - packLEDWord(&packet, 0); - - SAFE_FREE(&szReasonAnsi); - - SendDirectMessage(hContact, &packet); - - NetLog_Direct("Sent file deny direct."); -} - - -int CIcqProto::icq_sendFileSendDirectv7(filetransfer *ft, const char *pszFiles) -{ - char *szFilesAnsi = nullptr; - size_t wDescrLen = mir_strlen(ft->szDescription); - - if (!utf8_decode(pszFiles, &szFilesAnsi)) - szFilesAnsi = _strdup(pszFiles); // Legacy fix - size_t wFilesLen = mir_strlen(szFilesAnsi); - - icq_packet packet; - packDirectMsgHeader(&packet, 18 + wDescrLen + wFilesLen, DIRECT_MESSAGE, (WORD)ft->dwCookie, MTYPE_FILEREQ, 0, 0, 0); - packLEWord(&packet, WORD(wDescrLen + 1)); - packBuffer(&packet, (LPBYTE)ft->szDescription, wDescrLen + 1); - packLEDWord(&packet, 0); // listen port - packLEWord(&packet, WORD(wFilesLen + 1)); - packBuffer(&packet, (LPBYTE)szFilesAnsi, wFilesLen + 1); - packLEDWord(&packet, ft->dwTotalSize); - packLEDWord(&packet, 0); // listen port (again) - - SAFE_FREE(&szFilesAnsi); - - NetLog_Direct("Sending v%u file transfer request direct", 7); - - return SendDirectMessage(ft->hContact, &packet); -} - - -int CIcqProto::icq_sendFileSendDirectv8(filetransfer *ft, const char *pszFiles) -{ - char *szFilesAnsi = nullptr; - size_t wDescrLen = mir_strlen(ft->szDescription); - - if (!utf8_decode(pszFiles, &szFilesAnsi)) - szFilesAnsi = _strdup(pszFiles); // Legacy fix - size_t wFilesLen = mir_strlen(szFilesAnsi) + 1; - - icq_packet packet; - packDirectMsgHeader(&packet, 0x2E + 22 + wDescrLen + wFilesLen, DIRECT_MESSAGE, (WORD)ft->dwCookie, MTYPE_PLUGIN, 0, 0, 0); - packEmptyMsg(&packet); // message - packPluginTypeId(&packet, MTYPE_FILEREQ); - - packLEDWord(&packet, WORD(18 + wDescrLen + wFilesLen)); // Remaining length - packLEDWord(&packet, DWORD(wDescrLen)); // Description - packBuffer(&packet, (LPBYTE)ft->szDescription, wDescrLen); - packWord(&packet, 0x8c82); // Unknown (port?), seen 0x80F6 - packWord(&packet, 0x0222); // Unknown, seen 0x2e01 - packLEWord(&packet, WORD(wFilesLen)); - packBuffer(&packet, (LPBYTE)szFilesAnsi, wFilesLen); - packLEDWord(&packet, ft->dwTotalSize); - packLEDWord(&packet, 0x0008c82); // Unknown, (seen 0xf680 ~33000) - - SAFE_FREE(&szFilesAnsi); - - NetLog_Direct("Sending v%u file transfer request direct", 8); - - return SendDirectMessage(ft->hContact, &packet); -} - - -DWORD CIcqProto::icq_SendDirectMessage(MCONTACT hContact, const char *szMessage, size_t nBodyLength, cookie_message_data *pCookieData, char *szCap) -{ - DWORD dwCookie = AllocateCookie(CKT_MESSAGE, 0, hContact, (void*)pCookieData); - - // Pack the standard header - icq_packet packet; - packDirectMsgHeader(&packet, nBodyLength + (szCap ? 53 : 11), DIRECT_MESSAGE, dwCookie, (BYTE)pCookieData->bMessageType, 0, 0, 0); - - packLEWord(&packet, WORD(nBodyLength + 1)); // Length of message - packBuffer(&packet, (LPBYTE)szMessage, nBodyLength + 1); // Message - packMsgColorInfo(&packet); - if (szCap) { - packLEDWord(&packet, 0x00000026); // length of GUID - packBuffer(&packet, (LPBYTE)szCap, 0x26); // UTF-8 GUID - } - - if (SendDirectMessage(hContact, &packet)) - return dwCookie; // Success - - FreeCookie(dwCookie); // release cookie - return 0; // Failure -} - -void CIcqProto::icq_sendXtrazRequestDirect(MCONTACT hContact, DWORD dwCookie, char* szBody, size_t nBodyLen, WORD wType) -{ - icq_packet packet; - packDirectMsgHeader(&packet, 11 + getPluginTypeIdLen(wType) + nBodyLen, DIRECT_MESSAGE, dwCookie, MTYPE_PLUGIN, 0, 0, 1); - packEmptyMsg(&packet); // message (unused) - packPluginTypeId(&packet, wType); - - packLEDWord(&packet, DWORD(nBodyLen + 4)); - packLEDWord(&packet, DWORD(nBodyLen)); - packBuffer(&packet, (LPBYTE)szBody, nBodyLen); - - SendDirectMessage(hContact, &packet); -} - -void CIcqProto::icq_sendXtrazResponseDirect(MCONTACT hContact, WORD wCookie, char* szBody, size_t nBodyLen, WORD wType) -{ - icq_packet packet; - packDirectMsgHeader(&packet, getPluginTypeIdLen(wType) + 11 + nBodyLen, DIRECT_ACK, wCookie, MTYPE_PLUGIN, 0, 0, 0); - - packEmptyMsg(&packet); // Message (unused) - - packPluginTypeId(&packet, wType); - - packLEDWord(&packet, DWORD(nBodyLen + 4)); - packLEDWord(&packet, DWORD(nBodyLen)); - packBuffer(&packet, (LPBYTE)szBody, nBodyLen); - - SendDirectMessage(hContact, &packet); -} diff --git a/protocols/IcqOscarJ/src/dlgproc.cpp b/protocols/IcqOscarJ/src/dlgproc.cpp deleted file mode 100644 index 061538a074..0000000000 --- a/protocols/IcqOscarJ/src/dlgproc.cpp +++ /dev/null @@ -1,507 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2001-2004 Richard Hughes, Martin Öberg -// Copyright © 2004-2010 Joe Kucera, Bio -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// ChangeInfo Plugin stuff -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -#define DM_PROTOACK (WM_USER+10) - -static int DrawTextUtf(HDC hDC, char *text, LPRECT lpRect, UINT uFormat, LPSIZE lpSize) -{ - int res; - - WCHAR *tmp = make_unicode_string(text); - res = DrawTextW(hDC, tmp, -1, lpRect, uFormat); - if (lpSize) - GetTextExtentPoint32W(hDC, tmp, (int)mir_wstrlen(tmp), lpSize); - SAFE_FREE((void**)&tmp); - - return res; -} - -char* ChangeInfoData::GetItemSettingText(int i, char *buf, size_t bufsize) -{ - char *text = buf; - int alloced = 0; - - buf[0] = '\0'; - - const SettingItem &si = setting[i]; - SettingItemData &sid = settingData[i]; - if (sid.value == 0 && !(si.displayType & LIF_ZEROISVALID)) { - if (si.displayType & LIF_CHANGEONLY) - text = ICQTranslateUtfStatic(LPGEN(""), buf, bufsize); - else - text = ICQTranslateUtfStatic(LPGEN(""), buf, bufsize); - } - else { - switch (si.displayType & LIM_TYPE) { - case LI_STRING: - case LI_LONGSTRING: - text = BinaryToEscapes((char*)sid.value); - alloced = 1; - break; - - case LI_NUMBER: - _itoa(sid.value, text, 10); - break; - - case LI_LIST: - if (si.dbType == DBVT_ASCIIZ) - text = ICQTranslateUtfStatic((char*)sid.value, buf, bufsize); - else { - text = ICQTranslateUtfStatic(LPGEN("Unknown value"), buf, bufsize); - - FieldNamesItem *list = (FieldNamesItem*)si.pList; - if (list == timezonesField) { - HANDLE tz = TimeZone_CreateByContact(NULL, ppro->m_szModuleName, 0); - text = make_utf8_string_static(TimeZone_GetDescription(TimeZone_GetName(tz)), buf, bufsize); - break; - } - - for (int j = 0;; j++) { - if (list[j].code == sid.value) { - text = ICQTranslateUtfStatic(list[j].text, buf, bufsize); - break; - } - else if (!list[j].text) { - if (list[j].code == sid.value) - text = ICQTranslateUtfStatic("Unspecified", buf, bufsize); - break; - } - } - } - break; - } - } - - if (si.displayType & LIF_PASSWORD) { - if (sid.changed) { - for (int j = 0; text[j]; j++) - text[j] = '*'; - } - else { - if (alloced) { - SAFE_FREE(&text); - alloced = 0; - } - text = "********"; - } - } - if (text != buf) { - char *tmp = text; - - text = null_strcpy(buf, text, bufsize - 1); - if (alloced) - SAFE_FREE(&tmp); - } - - return text; -} - -void ChangeInfoData::PaintItemSetting(HDC hdc, RECT *rc, int i, UINT itemState) -{ - char str[MAX_PATH]; - char *text = GetItemSettingText(i, str, _countof(str)); - - const SettingItem &si = setting[i]; - SettingItemData &sid = settingData[i]; - if (sid.value == 0 && !(si.displayType & LIF_ZEROISVALID)) - SetTextColor(hdc, GetSysColor(COLOR_GRAYTEXT)); - - if ((si.displayType & LIM_TYPE) == LI_LIST && (itemState & CDIS_SELECTED || iEditItem == i)) { - RECT rcBtn = *rc; - rcBtn.left = rcBtn.right - rc->bottom + rc->top; - InflateRect(&rcBtn, -2, -2); - rc->right = rcBtn.left; - DrawFrameControl(hdc, &rcBtn, DFC_SCROLL, iEditItem == i ? DFCS_SCROLLDOWN | DFCS_PUSHED : DFCS_SCROLLDOWN); - } - DrawTextUtf(hdc, text, rc, DT_END_ELLIPSIS | DT_LEFT | DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER, nullptr); -} - -static int ChangeInfoDlg_Resize(HWND, LPARAM, UTILRESIZECONTROL *urc) -{ - switch (urc->wId) { - case IDC_LIST: - return RD_ANCHORX_WIDTH | RD_ANCHORY_HEIGHT; - - case IDC_SAVE: - return RD_ANCHORX_RIGHT | RD_ANCHORY_BOTTOM; - - case IDC_UPLOADING: - return RD_ANCHORX_WIDTH | RD_ANCHORY_BOTTOM; - } - - return RD_ANCHORX_LEFT | RD_ANCHORY_TOP; // default -} - - -INT_PTR CALLBACK ChangeInfoDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - ChangeInfoData* dat = (ChangeInfoData*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - - switch (msg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - - dat = new ChangeInfoData(); - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat); - - dat->hwndDlg = hwndDlg; - dat->ppro = (CIcqProto*)lParam; - dat->hwndList = GetDlgItem(hwndDlg, IDC_LIST); - - ListView_SetExtendedListViewStyle(dat->hwndList, LVS_EX_FULLROWSELECT); - dat->iEditItem = -1; - { - dat->hListFont = (HFONT)SendMessage(dat->hwndList, WM_GETFONT, 0, 0); - - LOGFONT lf; - GetObject(dat->hListFont, sizeof(lf), &lf); - lf.lfHeight -= 5; - HFONT hFont = CreateFontIndirect(&lf); - SendMessage(dat->hwndList, WM_SETFONT, (WPARAM)hFont, 0); - - // Prepare ListView Columns - RECT rc; - GetClientRect(dat->hwndList, &rc); - rc.right -= GetSystemMetrics(SM_CXVSCROLL); - - LV_COLUMN lvc = { 0 }; - lvc.mask = LVCF_WIDTH; - lvc.cx = rc.right / 3; - ListView_InsertColumn(dat->hwndList, 0, &lvc); - lvc.cx = rc.right - lvc.cx; - ListView_InsertColumn(dat->hwndList, 1, &lvc); - - // Prepare Setting Items - LV_ITEM lvi = { 0 }; - lvi.mask = LVIF_PARAM | LVIF_TEXT; - for (lvi.iItem = 0; lvi.iItem < settingCount; lvi.iItem++) { - wchar_t text[MAX_PATH]; - lvi.lParam = lvi.iItem; - lvi.pszText = text; - make_unicode_string_static(setting[lvi.iItem].szDescription, text, _countof(text)); - ListView_InsertItem(dat->hwndList, &lvi); - } - } - - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - return TRUE; - - case WM_NOTIFY: - switch (((LPNMHDR)lParam)->idFrom) { - case 0: - switch (((LPNMHDR)lParam)->code) { - case PSN_PARAMCHANGED: - dat->ppro = (CIcqProto*)((PSHNOTIFY*)lParam)->lParam; - dat->LoadSettingsFromDb(0); - { - char *pwd = dat->ppro->GetUserPassword(TRUE); - mir_strcpy(dat->Password, (pwd) ? pwd : ""); /// FIXME - } - break; - - case PSN_INFOCHANGED: - dat->LoadSettingsFromDb(1); - break; - - case PSN_KILLACTIVE: - dat->EndStringEdit(1); - dat->EndListEdit(1); - break; - - case PSN_APPLY: - if (dat->ChangesMade()) { - if (MessageBox(hwndDlg, TranslateT("You've made some changes to your ICQ details but it has not been saved to the server. Are you sure you want to close this dialog?"), TranslateT("Change ICQ Details"), MB_YESNOCANCEL) != IDYES) { - SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE); - return TRUE; - } - } - } - break; - - case IDC_LIST: - switch (((LPNMHDR)lParam)->code) { - case LVN_GETDISPINFO: - if (dat->iEditItem != -1) { - if (dat->editTopIndex != ListView_GetTopIndex(dat->hwndList)) { - dat->EndStringEdit(1); - dat->EndListEdit(1); - } - } - break; - - case NM_CUSTOMDRAW: - { - LPNMLVCUSTOMDRAW cd = (LPNMLVCUSTOMDRAW)lParam; - - switch (cd->nmcd.dwDrawStage) { - case CDDS_PREPAINT: - SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, CDRF_NOTIFYITEMDRAW); - return TRUE; - - case CDDS_ITEMPREPAINT: - if (dat->iEditItem != -1) { - if (dat->editTopIndex != ListView_GetTopIndex(dat->hwndList)) { - dat->EndStringEdit(1); - dat->EndListEdit(1); - } - } - { - RECT rcItem; - ListView_GetItemRect(dat->hwndList, cd->nmcd.dwItemSpec, &rcItem, LVIR_BOUNDS); - - if (GetWindowLongPtr(dat->hwndList, GWL_STYLE) & WS_DISABLED) { // Disabled List - SetTextColor(cd->nmcd.hdc, cd->clrText); - FillRect(cd->nmcd.hdc, &rcItem, GetSysColorBrush(COLOR_3DFACE)); - } - else if ((cd->nmcd.uItemState & CDIS_SELECTED || dat->iEditItem == (int)cd->nmcd.dwItemSpec) - && setting[cd->nmcd.lItemlParam].displayType != LI_DIVIDER) { // Selected item - SetTextColor(cd->nmcd.hdc, GetSysColor(COLOR_HIGHLIGHTTEXT)); - FillRect(cd->nmcd.hdc, &rcItem, GetSysColorBrush(COLOR_HIGHLIGHT)); - } - else { // Unselected item - SetTextColor(cd->nmcd.hdc, GetSysColor(COLOR_WINDOWTEXT)); - FillRect(cd->nmcd.hdc, &rcItem, GetSysColorBrush(COLOR_WINDOW)); - } - - HFONT hoFont = (HFONT)SelectObject(cd->nmcd.hdc, dat->hListFont); - - if (setting[cd->nmcd.lItemlParam].displayType == LI_DIVIDER) { - RECT rcLine; - SIZE textSize; - char str[MAX_PATH]; - char *szText = ICQTranslateUtfStatic(setting[cd->nmcd.lItemlParam].szDescription, str, MAX_PATH); - - SetTextColor(cd->nmcd.hdc, GetSysColor(COLOR_3DSHADOW)); - DrawTextUtf(cd->nmcd.hdc, szText, &rcItem, DT_CENTER | DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER, &textSize); - rcLine.top = (rcItem.top + rcItem.bottom) / 2 - 1; - rcLine.bottom = rcLine.top + 2; - rcLine.left = rcItem.left + 3; - rcLine.right = (rcItem.left + rcItem.right - textSize.cx) / 2 - 3; - DrawEdge(cd->nmcd.hdc, &rcLine, BDR_SUNKENOUTER, BF_RECT); - rcLine.left = (rcItem.left + rcItem.right + textSize.cx) / 2 + 3; - rcLine.right = rcItem.right - 3; - DrawEdge(cd->nmcd.hdc, &rcLine, BDR_SUNKENOUTER, BF_RECT); - } - else { - RECT rcItemDescr, rcItemValue; - char str[MAX_PATH]; - - ListView_GetSubItemRect(dat->hwndList, cd->nmcd.dwItemSpec, 0, LVIR_BOUNDS, &rcItemDescr); - ListView_GetSubItemRect(dat->hwndList, cd->nmcd.dwItemSpec, 1, LVIR_BOUNDS, &rcItemValue); - - rcItemDescr.right = rcItemValue.left; - rcItemDescr.left += 2; - DrawTextUtf(cd->nmcd.hdc, ICQTranslateUtfStatic(setting[cd->nmcd.lItemlParam].szDescription, str, MAX_PATH), &rcItemDescr, DT_END_ELLIPSIS | DT_LEFT | DT_NOCLIP | DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER, nullptr); - - dat->PaintItemSetting(cd->nmcd.hdc, &rcItemValue, cd->nmcd.lItemlParam, cd->nmcd.uItemState); - } - SelectObject(cd->nmcd.hdc, hoFont); - - SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, CDRF_SKIPDEFAULT); - - return TRUE; - } - } - } - break; - - case NM_CLICK: - { - LPNMLISTVIEW nm = (LPNMLISTVIEW)lParam; - LV_ITEM lvi; - RECT rc; - - dat->EndStringEdit(1); - dat->EndListEdit(1); - if (nm->iSubItem != 1) break; - lvi.mask = LVIF_PARAM | LVIF_STATE; - lvi.stateMask = 0xFFFFFFFF; - lvi.iItem = nm->iItem; lvi.iSubItem = nm->iSubItem; - ListView_GetItem(dat->hwndList, &lvi); - if (!(lvi.state & LVIS_SELECTED)) break; - ListView_EnsureVisible(dat->hwndList, lvi.iItem, FALSE); - ListView_GetSubItemRect(dat->hwndList, lvi.iItem, lvi.iSubItem, LVIR_BOUNDS, &rc); - dat->editTopIndex = ListView_GetTopIndex(dat->hwndList); - switch (setting[lvi.lParam].displayType & LIM_TYPE) { - case LI_STRING: - case LI_LONGSTRING: - case LI_NUMBER: - dat->BeginStringEdit(nm->iItem, &rc, lvi.lParam, 0); - break; - case LI_LIST: - dat->BeginListEdit(nm->iItem, &rc, lvi.lParam, 0); - break; - } - } - break; - - case LVN_KEYDOWN: - { - LPNMLVKEYDOWN nm = (LPNMLVKEYDOWN)lParam; - LV_ITEM lvi; - RECT rc; - - dat->EndStringEdit(1); - dat->EndListEdit(1); - if (nm->wVKey == VK_SPACE || nm->wVKey == VK_RETURN || nm->wVKey == VK_F2) nm->wVKey = 0; - if (nm->wVKey && (nm->wVKey < '0' || (nm->wVKey > '9' && nm->wVKey < 'A') || (nm->wVKey > 'Z' && nm->wVKey < VK_NUMPAD0) || nm->wVKey >= VK_F1)) - break; - lvi.mask = LVIF_PARAM | LVIF_STATE; - lvi.stateMask = 0xFFFFFFFF; - lvi.iItem = ListView_GetNextItem(dat->hwndList, -1, LVNI_ALL | LVNI_SELECTED); - if (lvi.iItem == -1) break; - lvi.iSubItem = 1; - ListView_GetItem(dat->hwndList, &lvi); - ListView_EnsureVisible(dat->hwndList, lvi.iItem, FALSE); - ListView_GetSubItemRect(dat->hwndList, lvi.iItem, lvi.iSubItem, LVIR_BOUNDS, &rc); - dat->editTopIndex = ListView_GetTopIndex(dat->hwndList); - switch (setting[lvi.lParam].displayType & LIM_TYPE) { - case LI_STRING: - case LI_LONGSTRING: - case LI_NUMBER: - dat->BeginStringEdit(lvi.iItem, &rc, lvi.lParam, nm->wVKey); - break; - case LI_LIST: - dat->BeginListEdit(lvi.iItem, &rc, lvi.lParam, nm->wVKey); - break; - } - SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE); - } - return TRUE; - - case NM_KILLFOCUS: - if (!IsStringEditWindow(GetFocus())) - dat->EndStringEdit(1); - if (!IsListEditWindow(GetFocus())) - dat->EndListEdit(1); - } - } - break; - - case WM_KILLFOCUS: - dat->EndStringEdit(1); - dat->EndListEdit(1); - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDCANCEL: - SendMessage(GetParent(hwndDlg), msg, wParam, lParam); - break; - - case IDC_SAVE: - if (!dat->SaveSettingsToDb()) - break; - - EnableDlgItem(hwndDlg, IDC_SAVE, FALSE); - EnableDlgItem(hwndDlg, IDC_LIST, FALSE); - SetDlgItemText(hwndDlg, IDC_UPLOADING, TranslateT("Upload in progress...")); - EnableDlgItem(hwndDlg, IDC_UPLOADING, TRUE); - ShowDlgItem(hwndDlg, IDC_UPLOADING, SW_SHOW); - dat->hAckHook = HookEventMessage(ME_PROTO_ACK, hwndDlg, DM_PROTOACK); - - if (!dat->UploadSettings()) { - EnableDlgItem(hwndDlg, IDC_SAVE, TRUE); - EnableDlgItem(hwndDlg, IDC_LIST, TRUE); - ShowDlgItem(hwndDlg, IDC_UPLOADING, SW_HIDE); - UnhookEvent(dat->hAckHook); - dat->hAckHook = nullptr; - } - } - break; - - case WM_SIZE: - if (IsIconic(hwndDlg)) - break; - - Utils_ResizeDialog(hwndDlg, g_plugin.getInst(), MAKEINTRESOURCEA(IDD_INFO_CHANGEINFO), ChangeInfoDlg_Resize); - { - RECT rc; // update listview column widths - GetClientRect(dat->hwndList, &rc); - rc.right -= GetSystemMetrics(SM_CXVSCROLL); - ListView_SetColumnWidth(dat->hwndList, 0, rc.right / 3); - ListView_SetColumnWidth(dat->hwndList, 1, rc.right - rc.right / 3); - } - break; - - case DM_PROTOACK: - { - ACKDATA *ack = (ACKDATA*)lParam; - int i, done; - - if (ack->type != ACKTYPE_SETINFO) break; - if (ack->result == ACKRESULT_SUCCESS) { - for (i = 0; i < _countof(dat->hUpload); i++) - if (dat->hUpload[i] && ack->hProcess == dat->hUpload[i]) - break; - - if (i == _countof(dat->hUpload)) break; - dat->hUpload[i] = nullptr; - for (done = 0, i = 0; i < _countof(dat->hUpload); i++) - done += dat->hUpload[i] == nullptr; - wchar_t buf[MAX_PATH]; - mir_snwprintf(buf, TranslateT("Upload in progress...%d%%"), 100 * done / (_countof(dat->hUpload))); - SetDlgItemText(hwndDlg, IDC_UPLOADING, buf); - if (done < _countof(dat->hUpload)) break; - - dat->ClearChangeFlags(); - UnhookEvent(dat->hAckHook); - dat->hAckHook = nullptr; - EnableDlgItem(hwndDlg, IDC_LIST, TRUE); - EnableDlgItem(hwndDlg, IDC_UPLOADING, FALSE); - SetDlgItemText(hwndDlg, IDC_UPLOADING, TranslateT("Upload complete")); - SendMessage(GetParent(hwndDlg), PSM_FORCECHANGED, 0, 0); - } - else if (ack->result == ACKRESULT_FAILED) { - UnhookEvent(dat->hAckHook); - dat->hAckHook = nullptr; - EnableDlgItem(hwndDlg, IDC_LIST, TRUE); - EnableDlgItem(hwndDlg, IDC_UPLOADING, FALSE); - SetDlgItemText(hwndDlg, IDC_UPLOADING, TranslateT("Upload FAILED")); - SendMessage(GetParent(hwndDlg), PSM_FORCECHANGED, 0, 0); - EnableDlgItem(hwndDlg, IDC_SAVE, TRUE); - } - } - break; - - case WM_DESTROY: - if (dat->hAckHook) { - UnhookEvent(dat->hAckHook); - dat->hAckHook = nullptr; - } - - DeleteObject((HFONT)SendMessage(dat->hwndList, WM_GETFONT, 0, 0)); - - dat->FreeStoredDbSettings(); - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0); - delete dat; - break; - } - return FALSE; -} diff --git a/protocols/IcqOscarJ/src/editlist.cpp b/protocols/IcqOscarJ/src/editlist.cpp deleted file mode 100644 index 165e09bf7f..0000000000 --- a/protocols/IcqOscarJ/src/editlist.cpp +++ /dev/null @@ -1,196 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2001-2004 Richard Hughes, Martin Öberg -// Copyright © 2004-2009 Joe Kucera, Bio -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// ChangeInfo Plugin stuff -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -static ChangeInfoData *dataListEdit = nullptr; -static HWND hwndListEdit = nullptr; - -static LRESULT CALLBACK ListEditSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) { - case WM_LBUTTONUP: - mir_callNextSubclass(hwnd, ListEditSubclassProc, msg, wParam, lParam); - { - POINT pt = { (short)LOWORD(lParam), (short)HIWORD(lParam) }; - ClientToScreen(hwnd, &pt); - if (SendMessage(hwnd, WM_NCHITTEST, 0, MAKELPARAM(pt.x, pt.y)) == HTVSCROLL) - break; - - int i = SendMessage(hwnd, LB_GETCURSEL, 0, 0); - if (dataListEdit) - dataListEdit->EndListEdit(i != LB_ERR); - } - return 0; - - case WM_CHAR: - if (wParam != '\r') break; - { - int i = SendMessage(hwnd, LB_GETCURSEL, 0, 0); - if (dataListEdit) - dataListEdit->EndListEdit(i != LB_ERR); - } - return 0; - - case WM_KILLFOCUS: - if (dataListEdit) - dataListEdit->EndListEdit(1); - return 0; - } - return mir_callNextSubclass(hwnd, ListEditSubclassProc, msg, wParam, lParam); -} - -void ChangeInfoData::BeginListEdit(int iItem, RECT *rc, int iSetting, WORD wVKey) -{ - if (dataListEdit) - dataListEdit->EndListEdit(0); - - POINT pt = { 0, 0 }; - ClientToScreen(hwndList, &pt); - OffsetRect(rc, pt.x, pt.y); - InflateRect(rc, -2, -2); - rc->left -= 2; - iEditItem = iItem; - ListView_RedrawItems(hwndList, iEditItem, iEditItem); - UpdateWindow(hwndList); - - dataListEdit = this; - hwndListEdit = CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TOPMOST, L"LISTBOX", L"", WS_POPUP | WS_BORDER | WS_VSCROLL, - rc->left, rc->bottom, rc->right - rc->left, 150, nullptr, nullptr, g_plugin.getInst(), nullptr); - SendMessage(hwndListEdit, WM_SETFONT, (WPARAM)hListFont, 0); - int itemHeight = SendMessage(hwndListEdit, LB_GETITEMHEIGHT, 0, 0); - - const SettingItem &si = setting[iSetting]; - SettingItemData &sid = settingData[iSetting]; - FieldNamesItem *list = (FieldNamesItem*)si.pList; - - // some country codes were changed leaving old details uknown, convert it for the user - if (list == countryField) { - if (sid.value == 420) - sid.value = 42; // conversion of obsolete codes (OMG!) - else if (sid.value == 421) - sid.value = 4201; - else if (sid.value == 102) - sid.value = 1201; - } - - if (list == timezonesField) { - TimeZone_PrepareList(NULL, ppro->m_szModuleName, hwndListEdit, TZF_PLF_LB); - } - else { - int j, n = ListBoxAddStringUtf(hwndListEdit, "Unspecified"); - for (j = 0;; j++) - if (!list[j].text) { - SendMessage(hwndListEdit, LB_SETITEMDATA, n, j); - if ((sid.value == 0 && list[j].code == 0) || (si.dbType != DBVT_ASCIIZ && sid.value == list[j].code)) - SendMessage(hwndListEdit, LB_SETCURSEL, n, 0); - break; - } - - for (j = 0; list[j].text; j++) { - char str[MAX_PATH]; - n = ListBoxAddStringUtf(hwndListEdit, list[j].text); - SendMessage(hwndListEdit, LB_SETITEMDATA, n, j); - if ((si.dbType == DBVT_ASCIIZ && (!mir_strcmp((char*)sid.value, list[j].text)) - || (si.dbType == DBVT_ASCIIZ && (!mir_strcmp((char*)sid.value, ICQTranslateUtfStatic(list[j].text, str, MAX_PATH)))) - || ((char*)sid.value == nullptr && list[j].code == 0)) - || (si.dbType != DBVT_ASCIIZ && sid.value == list[j].code)) - SendMessage(hwndListEdit, LB_SETCURSEL, n, 0); - } - SendMessage(hwndListEdit, LB_SETTOPINDEX, SendMessage(hwndListEdit, LB_GETCURSEL, 0, 0) - 3, 0); - } - - int listCount = SendMessage(hwndListEdit, LB_GETCOUNT, 0, 0); - if (itemHeight * listCount < 150) - SetWindowPos(hwndListEdit, nullptr, 0, 0, rc->right - rc->left, itemHeight * listCount + GetSystemMetrics(SM_CYBORDER) * 2, SWP_NOZORDER | SWP_NOMOVE); - mir_subclassWindow(hwndListEdit, ListEditSubclassProc); - AnimateWindow(hwndListEdit, 200, AW_SLIDE | AW_ACTIVATE | AW_VER_POSITIVE); - ShowWindow(hwndListEdit, SW_SHOW); - SetFocus(hwndListEdit); - if (wVKey) - PostMessage(hwndListEdit, WM_KEYDOWN, wVKey, 0); -} - -void ChangeInfoData::EndListEdit(int save) -{ - if (hwndListEdit == nullptr || iEditItem == -1 || this != dataListEdit) - return; - - if (save) { - const SettingItem &si = setting[iEditItem]; - SettingItemData &sid = settingData[iEditItem]; - - int iItem = SendMessage(hwndListEdit, LB_GETCURSEL, 0, 0); - int i = SendMessage(hwndListEdit, LB_GETITEMDATA, iItem, 0); - if (iItem != -1 && i != -1) { - FieldNamesItem *list = (FieldNamesItem*)si.pList; - if (list == timezonesField) { - TimeZone_StoreListResult(NULL, ppro->m_szModuleName, hwndListEdit, TZF_PLF_LB); - list[i = 0].code = ppro->getDword("Timezone", 0); - } - - FieldNamesItem &pItem = list[i]; - - if (si.dbType == DBVT_ASCIIZ) { - char *szNewValue = pItem.text; - if (pItem.code || (si.displayType & LIF_ZEROISVALID)) { - sid.changed = mir_strcmp(szNewValue, (char*)sid.value); - SAFE_FREE((void**)&sid.value); - sid.value = (LPARAM)null_strdup(szNewValue); - } - else { - sid.changed = (char*)sid.value != nullptr; - SAFE_FREE((void**)&sid.value); - } - } - else { - sid.changed = pItem.code != sid.value; - sid.value = pItem.code; - } - - if (sid.changed) { - char buf[MAX_PATH]; - wchar_t tbuf[MAX_PATH]; - if (make_unicode_string_static(ICQTranslateUtfStatic(pItem.text, buf, _countof(buf)), tbuf, _countof(buf))) - ListView_SetItemText(hwndList, iEditItem, 1, tbuf); - - EnableDlgItem(GetParent(hwndList), IDC_SAVE, TRUE); - } - } - } - ListView_RedrawItems(hwndList, iEditItem, iEditItem); - iEditItem = -1; - dataListEdit = nullptr; - DestroyWindow(hwndListEdit); - hwndListEdit = nullptr; -} - -int IsListEditWindow(HWND hwnd) -{ - if (hwnd == hwndListEdit) return 1; - return 0; -} diff --git a/protocols/IcqOscarJ/src/editstring.cpp b/protocols/IcqOscarJ/src/editstring.cpp deleted file mode 100644 index ef689445da..0000000000 --- a/protocols/IcqOscarJ/src/editstring.cpp +++ /dev/null @@ -1,336 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2001-2004 Richard Hughes, Martin Öberg -// Copyright © 2004-2009 Joe Kucera, Bio -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// ChangeInfo Plugin stuff -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -static ChangeInfoData *dataStringEdit = nullptr; -static HWND hwndEdit = nullptr, hwndExpandButton = nullptr, hwndUpDown = nullptr; - -static const char escapes[] = -{ - 'a','\a', - 'b','\b', - 'e',27, - 'f','\f', - 'r','\r', - 't','\t', - 'v','\v', - '\\','\\' -}; - -static void EscapesToMultiline(WCHAR *str, PDWORD selStart, PDWORD selEnd) -{ - // converts "\\n" and "\\t" to "\r\n" and "\t" because a multi-line edit box can show them properly - DWORD i; - - for (i = 0; *str; str++, i++) { - if (*str != '\\') continue; - if (str[1] == 'n') { - *str++ = '\r'; - i++; - *str = '\n'; - } - else if (str[1] == 't') { - *str = '\t'; - memmove(str + 1, str + 2, sizeof(WCHAR)*(mir_wstrlen(str) - 1)); - - if (*selStart > i)--*selStart; - if (*selEnd > i)--*selEnd; - } - } -} - -static void EscapesToBinary(char *str) -{ - for (; *str; str++) { - if (*str != '\\') continue; - if (str[1] == 'n') { *str++ = '\r'; *str = '\n'; continue; } - if (str[1] == '0') { - char *codeend; - *str = (char)strtol(str + 1, &codeend, 8); - if (*str == 0) { *str = '\\'; continue; } - memmove(str + 1, codeend, mir_strlen(codeend) + 1); - continue; - } - for (int i = 0; i < _countof(escapes); i += 2) - if (str[1] == escapes[i]) { - *str = escapes[i + 1]; - memmove(str + 1, str + 2, mir_strlen(str) - 1); - break; - } - } -} - -char *BinaryToEscapes(char *str) -{ - int extra = 10, len = (int)mir_strlen(str) + 11, i; - char *out, *pout; - - out = pout = (char*)SAFE_MALLOC(len); - for (; *str; str++) { - if ((unsigned char)*str >= ' ') { - *pout++ = *str; - continue; - } - if (str[0] == '\r' && str[1] == '\n') { - *pout++ = '\\'; - *pout++ = 'n'; - str++; - continue; - } - if (extra < 3) { - extra += 8; len += 8; - pout = out = (char*)SAFE_REALLOC(out, len); - } - *pout++ = '\\'; - for (i = 0; i < _countof(escapes); i += 2) - if (*str == escapes[i + 1]) { - *pout++ = escapes[i]; - extra--; - break; - } - if (i < _countof(escapes)) continue; - *pout++ = '0'; extra--; - if (*str >= 8) { - *pout++ = (*str >> 3) + '0'; - extra--; - } - *pout++ = (*str & 7) + '0'; extra--; - } - *pout = '\0'; - return out; -} - -static LRESULT CALLBACK StringEditSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) { - case WM_KEYDOWN: - if (wParam == VK_ESCAPE) { - if (dataStringEdit) - dataStringEdit->EndStringEdit(0); - return 0; - } - if (wParam == VK_RETURN) { - if (GetWindowLongPtr(hwnd, GWL_STYLE) & ES_MULTILINE && !(GetKeyState(VK_CONTROL) & 0x8000)) break; - if (dataStringEdit) - dataStringEdit->EndStringEdit(1); - return 0; - } - break; - - case WM_GETDLGCODE: - return DLGC_WANTALLKEYS | mir_callNextSubclass(hwnd, StringEditSubclassProc, msg, wParam, lParam); - - case WM_KILLFOCUS: - if ((HWND)wParam == hwndExpandButton) break; - if (dataStringEdit) - dataStringEdit->EndStringEdit(1); - return 0; - } - return mir_callNextSubclass(hwnd, StringEditSubclassProc, msg, wParam, lParam); -} - -static LRESULT CALLBACK ExpandButtonSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) { - case WM_LBUTTONUP: - if (GetCapture() == hwnd) { - //do expand - RECT rcStart, rcEnd; - DWORD selStart, selEnd; - WCHAR *text; - BOOL animEnabled = TRUE; - - GetWindowRect(hwndEdit, &rcStart); - InflateRect(&rcStart, 2, 2); - - text = GetWindowTextUcs(hwndEdit); - SendMessage(hwndEdit, EM_GETSEL, (WPARAM)&selStart, (LPARAM)&selEnd); - DestroyWindow(hwndEdit); - EscapesToMultiline(text, &selStart, &selEnd); - hwndEdit = CreateWindowExA(WS_EX_TOOLWINDOW, "EDIT", "", WS_POPUP | WS_BORDER | WS_VISIBLE | ES_WANTRETURN | ES_AUTOVSCROLL | WS_VSCROLL | ES_MULTILINE, rcStart.left, rcStart.top, rcStart.right - rcStart.left, rcStart.bottom - rcStart.top, nullptr, nullptr, g_plugin.getInst(), nullptr); - SetWindowTextUcs(hwndEdit, text); - mir_subclassWindow(hwndEdit, StringEditSubclassProc); - SendMessage(hwndEdit, WM_SETFONT, (WPARAM)dataStringEdit->hListFont, 0); - SendMessage(hwndEdit, EM_SETSEL, selStart, selEnd); - SetFocus(hwndEdit); - - rcEnd.left = rcStart.left; rcEnd.top = rcStart.top; - rcEnd.right = rcEnd.left + 350; - rcEnd.bottom = rcEnd.top + 150; - if (LOBYTE(LOWORD(GetVersion())) > 4 || HIBYTE(LOWORD(GetVersion())) > 0) - SystemParametersInfo(SPI_GETCOMBOBOXANIMATION, 0, &animEnabled, FALSE); - if (animEnabled) { - DWORD startTime, timeNow; - startTime = GetTickCount(); - for (;;) { - UpdateWindow(hwndEdit); - timeNow = GetTickCount(); - if (timeNow > startTime + 200) break; - SetWindowPos(hwndEdit, nullptr, rcEnd.left, rcEnd.top, (rcEnd.right - rcStart.right)*(timeNow - startTime) / 200 + rcStart.right - rcEnd.left, (rcEnd.bottom - rcStart.bottom)*(timeNow - startTime) / 200 + rcStart.bottom - rcEnd.top, SWP_NOZORDER); - } - } - SetWindowPos(hwndEdit, nullptr, rcEnd.left, rcEnd.top, rcEnd.right - rcEnd.left, rcEnd.bottom - rcEnd.top, SWP_NOZORDER); - - DestroyWindow(hwnd); - hwndExpandButton = nullptr; - - SAFE_FREE((void**)&text); - } - break; - } - return mir_callNextSubclass(hwnd, ExpandButtonSubclassProc, msg, wParam, lParam); -} - -void ChangeInfoData::BeginStringEdit(int iItem, RECT *rc, int i, WORD wVKey) -{ - char *szValue; - char str[80]; - int alloced = 0; - - EndStringEdit(0); - InflateRect(rc, -2, -2); - rc->left -= 2; - - const SettingItem &si = setting[i]; - SettingItemData &sid = settingData[i]; - - if (si.displayType & LIF_PASSWORD && !sid.changed) - szValue = " "; - else if ((si.displayType & LIM_TYPE) == LI_NUMBER) { - szValue = str; - mir_snprintf(str, "%d", sid.value); - } - else if (sid.value) { - szValue = BinaryToEscapes((char*)sid.value); - alloced = 1; - } - else szValue = ""; - - iEditItem = iItem; - - if ((si.displayType & LIM_TYPE) == LI_LONGSTRING) { - rc->right -= rc->bottom - rc->top; - hwndExpandButton = CreateWindowA("BUTTON", "", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON | BS_ICON, rc->right, rc->top, rc->bottom - rc->top, rc->bottom - rc->top, hwndList, nullptr, g_plugin.getInst(), nullptr); - SendMessage(hwndExpandButton, BM_SETIMAGE, IMAGE_ICON, (LPARAM)IcoLib_GetIconByHandle(iconList[0].hIcolib)); - mir_subclassWindow(hwndExpandButton, ExpandButtonSubclassProc); - } - - dataStringEdit = this; - hwndEdit = CreateWindow(L"EDIT", L"", WS_VISIBLE | WS_CHILD | ES_AUTOHSCROLL | ((si.displayType&LIM_TYPE) == LI_NUMBER ? ES_NUMBER : 0) | (si.displayType&LIF_PASSWORD ? ES_PASSWORD : 0), rc->left, rc->top, rc->right - rc->left, rc->bottom - rc->top, hwndList, nullptr, g_plugin.getInst(), nullptr); - SetWindowTextUtf(hwndEdit, szValue); - if (alloced) SAFE_FREE(&szValue); - mir_subclassWindow(hwndEdit, StringEditSubclassProc); - SendMessage(hwndEdit, WM_SETFONT, (WPARAM)hListFont, 0); - if ((si.displayType & LIM_TYPE) == LI_NUMBER) { - int *range = (int*)si.pList; - RECT rcUpDown; - hwndUpDown = CreateWindow(UPDOWN_CLASS, L"", WS_VISIBLE | WS_CHILD | UDS_AUTOBUDDY | UDS_ALIGNRIGHT | UDS_HOTTRACK | UDS_NOTHOUSANDS | UDS_SETBUDDYINT, 0, 0, 0, 0, hwndList, nullptr, g_plugin.getInst(), nullptr); - SendMessage(hwndUpDown, UDM_SETRANGE32, range[0], range[1]); - SendMessage(hwndUpDown, UDM_SETPOS32, 0, sid.value); - if (!(si.displayType & LIF_ZEROISVALID) && sid.value == 0) - SetWindowTextA(hwndEdit, ""); - GetClientRect(hwndUpDown, &rcUpDown); - rc->right -= rcUpDown.right; - SetWindowPos(hwndEdit, nullptr, 0, 0, rc->right - rc->left, rc->bottom - rc->top, SWP_NOZORDER | SWP_NOMOVE); - } - SendMessage(hwndEdit, EM_SETSEL, 0, (LPARAM)-1); - SetFocus(hwndEdit); - PostMessage(hwndEdit, WM_KEYDOWN, wVKey, 0); -} - -void ChangeInfoData::EndStringEdit(int save) -{ - if (hwndEdit == nullptr || iEditItem == -1 || this != dataStringEdit) - return; - - if (save) { - char *text = (char*)SAFE_MALLOC(GetWindowTextLength(hwndEdit) + 1); - const SettingItem &si = setting[iEditItem]; - SettingItemData &sid = settingData[iEditItem]; - - GetWindowTextA(hwndEdit, (char*)text, GetWindowTextLength(hwndEdit) + 1); - EscapesToBinary(text); - if ((si.displayType & LIM_TYPE) == LI_NUMBER) { - LPARAM newValue; - int *range = (int*)si.pList; - newValue = atoi(text); - if (newValue) { - if (newValue < range[0]) newValue = range[0]; - if (newValue > range[1]) newValue = range[1]; - } - sid.changed = sid.value != newValue; - sid.value = newValue; - SAFE_FREE(&text); - } - else { - if (!(si.displayType & LIF_PASSWORD)) { - SAFE_FREE(&text); - text = GetWindowTextUtf(hwndEdit); - EscapesToBinary(text); - } - if ((si.displayType & LIF_PASSWORD && mir_strcmp(text, " ")) || - (!(si.displayType & LIF_PASSWORD) && mir_strcmp(text, (char*)sid.value) && (mir_strlen(text) + mir_strlen((char*)sid.value)))) { - SAFE_FREE((void**)&sid.value); - if (mir_strlen(text)) - sid.value = (LPARAM)text; - else { - sid.value = 0; - SAFE_FREE(&text); - } - sid.changed = 1; - } - } - - if (sid.changed) { - wchar_t tbuf[MAX_PATH]; - - GetWindowText(hwndEdit, tbuf, _countof(tbuf)); - ListView_SetItemText(hwndList, iEditItem, 1, tbuf); - - EnableDlgItem(hwndDlg, IDC_SAVE, TRUE); - } - } - - ListView_RedrawItems(hwndList, iEditItem, iEditItem); - iEditItem = -1; - dataStringEdit = nullptr; - DestroyWindow(hwndEdit); - hwndEdit = nullptr; - if (hwndExpandButton) DestroyWindow(hwndExpandButton); - hwndExpandButton = nullptr; - if (hwndUpDown) DestroyWindow(hwndUpDown); - hwndUpDown = nullptr; -} - -int IsStringEditWindow(HWND hwnd) -{ - if (hwnd == hwndEdit) return 1; - if (hwnd == hwndExpandButton) return 1; - if (hwnd == hwndUpDown) return 1; - return 0; -} diff --git a/protocols/IcqOscarJ/src/fam_01service.cpp b/protocols/IcqOscarJ/src/fam_01service.cpp deleted file mode 100644 index e9a1048e8a..0000000000 --- a/protocols/IcqOscarJ/src/fam_01service.cpp +++ /dev/null @@ -1,856 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// Handles packets from Service family -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -extern capstr capXStatus[]; - -void CIcqProto::handleServiceFam(BYTE *pBuffer, size_t wBufferLength, snac_header *pSnacHeader, serverthread_info *info) -{ - icq_packet packet; - - switch (pSnacHeader->wSubtype) { - - case ICQ_SERVER_READY: - debugLogA("Server is ready and is requesting my Family versions"); - debugLogA("Sending my Families"); - - // This packet is a response to SRV_FAMILIES SNAC(1,3). - // This tells the server which SNAC families and their corresponding - // versions which the client understands. This also seems to identify - // the client as an ICQ vice AIM client to the server. - // Miranda mimics the behaviour of ICQ 6 - serverPacketInit(&packet, 54); - packFNACHeader(&packet, ICQ_SERVICE_FAMILY, ICQ_CLIENT_FAMILIES); - packDWord(&packet, 0x00220001); - packDWord(&packet, 0x00010004); - packDWord(&packet, 0x00130004); - packDWord(&packet, 0x00020001); - packDWord(&packet, 0x00030001); - packDWord(&packet, 0x00150001); - packDWord(&packet, 0x00040001); - packDWord(&packet, 0x00060001); - packDWord(&packet, 0x00090001); - packDWord(&packet, 0x000a0001); - packDWord(&packet, 0x000b0001); - sendServPacket(&packet); - break; - - case ICQ_SERVER_FAMILIES2: - /* This is a reply to CLI_FAMILIES and it tells the client which families and their versions that this server understands. - * We send a rate request packet */ - debugLogA("Server told me his Family versions"); - debugLogA("Requesting Rate Information"); - - serverPacketInit(&packet, 10); - packFNACHeader(&packet, ICQ_SERVICE_FAMILY, ICQ_CLIENT_REQ_RATE_INFO); - sendServPacket(&packet); - break; - - case ICQ_SERVER_RATE_INFO: - debugLogA("Server sent Rate Info"); - - /* init rates management */ - m_rates = new rates(this, pBuffer, wBufferLength); - - /* ack rate levels */ - debugLogA("Sending Rate Info Ack"); - - m_rates->initAckPacket(&packet); - sendServPacket(&packet); - - /* CLI_REQINFO - This command requests from the server certain information about the client that is stored on the server. */ - debugLogA("Sending CLI_REQINFO"); - - serverPacketInit(&packet, 10); - packFNACHeader(&packet, ICQ_SERVICE_FAMILY, ICQ_CLIENT_REQINFO); - sendServPacket(&packet); - - if (m_bSsiEnabled) { - cookie_servlist_action* ack; - DWORD dwCookie; - - DWORD dwLastUpdate = getDword("SrvLastUpdate", 0); - WORD wRecordCount = getWord("SrvRecordCount", 0); - - // CLI_REQLISTS - we want to use SSI - debugLogA("Requesting roster rights"); - - serverPacketInit(&packet, 16); - packFNACHeader(&packet, ICQ_LISTS_FAMILY, ICQ_LISTS_CLI_REQLISTS); - packTLVWord(&packet, 0x0B, 0x000F); // mimic ICQ 6 - sendServPacket(&packet); - - if (!wRecordCount) { // CLI_REQROSTER - // we do not have any data - request full list - debugLogA("Requesting full roster"); - - serverPacketInit(&packet, 10); - ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action)); - if (ack) { // we try to use standalone cookie if available - ack->dwAction = SSA_CHECK_ROSTER; // loading list - dwCookie = AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_CLI_REQUEST, 0, ack); - } - else // if not use that old fake - dwCookie = ICQ_LISTS_CLI_REQUEST << 0x10; - - packFNACHeader(&packet, ICQ_LISTS_FAMILY, ICQ_LISTS_CLI_REQUEST, 0, dwCookie); - sendServPacket(&packet); - } - else { // CLI_CHECKROSTER - debugLogA("Requesting roster check"); - - serverPacketInit(&packet, 16); - ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action)); - if (ack) { // TODO: rewrite - use get list service for empty list - // we try to use standalone cookie if available - ack->dwAction = SSA_CHECK_ROSTER; // loading list - dwCookie = AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_CLI_CHECK, 0, ack); - } - else // if not use that old fake - dwCookie = ICQ_LISTS_CLI_CHECK << 0x10; - - packFNACHeader(&packet, ICQ_LISTS_FAMILY, ICQ_LISTS_CLI_CHECK, 0, dwCookie); - // check if it was not changed elsewhere (force reload, set that setting to zero) - if (IsServerGroupsDefined()) { - packDWord(&packet, dwLastUpdate); // last saved time - packWord(&packet, wRecordCount); // number of records saved - } - else { // we need to get groups info into DB, force receive list - packDWord(&packet, 0); // last saved time - packWord(&packet, 0); // number of records saved - } - sendServPacket(&packet); - } - } - - // CLI_REQLOCATION - debugLogA("Requesting Location rights"); - - serverPacketInit(&packet, 10); - packFNACHeader(&packet, ICQ_LOCATION_FAMILY, ICQ_LOCATION_CLI_REQ_RIGHTS); - sendServPacket(&packet); - - // CLI_REQBUDDY - debugLogA("Requesting Client-side contactlist rights"); - - serverPacketInit(&packet, 16); - packFNACHeader(&packet, ICQ_BUDDY_FAMILY, ICQ_USER_CLI_REQBUDDY); - // Query flags: 1 = Enable Avatars - // 2 = Enable offline status message notification - // 4 = Enable Avatars for offline contacts - // 8 = Use reject for not authorized contacts - packTLVWord(&packet, 0x05, 0x0007); - sendServPacket(&packet); - - // CLI_REQICBM - debugLogA("Sending CLI_REQICBM"); - - serverPacketInit(&packet, 10); - packFNACHeader(&packet, ICQ_MSG_FAMILY, ICQ_MSG_CLI_REQICBM); - sendServPacket(&packet); - - // CLI_REQBOS - debugLogA("Sending CLI_REQBOS"); - - serverPacketInit(&packet, 10); - packFNACHeader(&packet, ICQ_BOS_FAMILY, ICQ_PRIVACY_REQ_RIGHTS); - sendServPacket(&packet); - break; - - case ICQ_SERVER_PAUSE: - debugLogA("Server is going down in a few seconds... (Flags: %u)", pSnacHeader->wFlags); - // This is the list of groups that we want to have on the next server - serverPacketInit(&packet, 30); - packFNACHeader(&packet, ICQ_SERVICE_FAMILY, ICQ_CLIENT_PAUSE_ACK); - packWord(&packet, ICQ_SERVICE_FAMILY); - packWord(&packet, ICQ_LISTS_FAMILY); - packWord(&packet, ICQ_LOCATION_FAMILY); - packWord(&packet, ICQ_BUDDY_FAMILY); - packWord(&packet, ICQ_EXTENSIONS_FAMILY); - packWord(&packet, ICQ_MSG_FAMILY); - packWord(&packet, 0x06); - packWord(&packet, ICQ_BOS_FAMILY); - packWord(&packet, ICQ_LOOKUP_FAMILY); - packWord(&packet, ICQ_STATS_FAMILY); - sendServPacket(&packet); - - debugLogA("Sent server pause ack"); - break; - - case ICQ_SERVER_MIGRATIONREQ: - debugLogA("Server migration requested (Flags: %u)", pSnacHeader->wFlags); - - pBuffer += 2; // Unknown, seen: 0 - wBufferLength -= 2; - { - oscar_tlv_chain *chain = readIntoTLVChain(&pBuffer, wBufferLength, 0); - - if (info->cookieDataLen > 0) - SAFE_FREE((void**)&info->cookieData); - - info->newServer = chain->getString(0x05, 1); - info->newServerSSL = chain->getNumber(0x8E, 1); - info->cookieData = (BYTE*)chain->getString(0x06, 1); - info->cookieDataLen = chain->getLength(0x06, 1); - - disposeChain(&chain); - - if (!info->newServer || !info->cookieData) { - icq_LogMessage(LOG_FATAL, LPGEN("A server migration has failed because the server returned invalid data. You must reconnect manually.")); - SAFE_FREE(&info->newServer); - SAFE_FREE((void**)&info->cookieData); - info->cookieDataLen = 0; - info->isNewServerReady = false; - return; - } - - debugLogA("Migration has started. New server will be %s", info->newServer); - - m_iDesiredStatus = m_iStatus; - SetCurrentStatus(ID_STATUS_CONNECTING); // revert to connecting state - - info->isNewServerReady = info->isMigrating = true; - } - break; - - case ICQ_SERVER_NAME_INFO: // This is the reply to CLI_REQINFO - debugLogA("Received self info"); - { - BYTE bUinLen; - unpackByte(&pBuffer, &bUinLen); - pBuffer += bUinLen; - pBuffer += 4; /* warning level & user class */ - wBufferLength -= 5 + bUinLen; - - // This is during the login sequence - if (pSnacHeader->dwRef == ICQ_CLIENT_REQINFO << 0x10) { - // TLV(x01) User type? - // TLV(x0C) Empty CLI2CLI Direct connection info - // TLV(x0A) External IP - // TLV(x0F) Number of seconds that user has been online - // TLV(x03) The online since time. - // TLV(x0A) External IP again - // TLV(x22) Unknown - // TLV(x1E) Unknown: empty. - // TLV(x05) Member of ICQ since. - // TLV(x14) Unknown - oscar_tlv_chain *chain = readIntoTLVChain(&pBuffer, wBufferLength, 0); - - // Save external IP - DWORD dwValue = chain->getDWord(0x0A, 1); - setDword("IP", dwValue); - - // Save member since timestamp - dwValue = chain->getDWord(0x05, 1); - if (dwValue) setDword("MemberTS", dwValue); - - dwValue = chain->getDWord(0x03, 1); - setDword("LogonTS", dwValue ? dwValue : time(0)); - - disposeChain(&chain); - - // If we are in SSI mode, this is sent after the list is acked instead - // to make sure that we don't set status before seing the visibility code - if (!m_bSsiEnabled || info->isMigrating) - handleServUINSettings(wListenPort, info); - } - } - break; - - case ICQ_SERVER_RATE_CHANGE: - if (wBufferLength >= 2) { - WORD wStatus, wClass; - DWORD dwLevel; - // We now have global rate management, although controlled are only some - // areas. This should not arrive in most cases. If it does, update our - // local rate levels & issue broadcast. - unpackWord(&pBuffer, &wStatus); - unpackWord(&pBuffer, &wClass); - pBuffer += 20; - unpackDWord(&pBuffer, &dwLevel); - { - mir_cslock l(m_ratesMutex); - m_rates->updateLevel(wClass, dwLevel); - } - - if (wStatus == 2 || wStatus == 3) { - // this is only the simplest solution, needs rate management to every section - ProtoBroadcastAck(NULL, ICQACKTYPE_RATEWARNING, ACKRESULT_STATUS, (HANDLE)wClass, wStatus); - if (wStatus == 2) - debugLogA("Rates #%u: Alert", wClass); - else - debugLogA("Rates #%u: Limit", wClass); - } - else if (wStatus == 4) { - ProtoBroadcastAck(NULL, ICQACKTYPE_RATEWARNING, ACKRESULT_STATUS, (HANDLE)wClass, wStatus); - debugLogA("Rates #%u: Clear", wClass); - } - } - - break; - - case ICQ_SERVER_REDIRECT_SERVICE: // reply to family request, got new connection point - { - oscar_tlv_chain *pChain = nullptr; - cookie_family_request *pCookieData; - - if (!(pChain = readIntoTLVChain(&pBuffer, wBufferLength, 0))) { - debugLogA("Received Broken Redirect Service SNAC(1,5)."); - break; - } - - // pick request data - WORD wFamily = pChain->getWord(0x0D, 1); - if ((!FindCookie(pSnacHeader->dwRef, nullptr, (void**)&pCookieData)) || (pCookieData->wFamily != wFamily)) { - disposeChain(&pChain); - debugLogA("Received unexpected SNAC(1,5), skipping."); - break; - } - - FreeCookie(pSnacHeader->dwRef); - - // new family entry point received - char *pServer = pChain->getString(0x05, 1); - BYTE bServerSSL = pChain->getNumber(0x8E, 1); - char *pCookie = pChain->getString(0x06, 1); - WORD wCookieLen = pChain->getLength(0x06, 1); - - if (!pServer || !pCookie) { - debugLogA("Server returned invalid data, family unavailable."); - - SAFE_FREE(&pServer); - SAFE_FREE(&pCookie); - SAFE_FREE((void**)&pCookieData); - disposeChain(&pChain); - break; - } - - // Get new family server ip and port - WORD wPort = info->wServerPort; // get default port - parseServerAddress(pServer, &wPort); - - // establish connection - NETLIBOPENCONNECTION nloc = { 0 }; - if (m_bGatewayMode) - nloc.flags |= NLOCF_HTTPGATEWAY; - nloc.szHost = pServer; - nloc.wPort = wPort; - - HNETLIBCONN hConnection = NetLib_OpenConnection(m_hNetlibUser, wFamily == ICQ_AVATAR_FAMILY ? "Avatar " : nullptr, &nloc); - - if (hConnection == nullptr) - debugLogA("Unable to connect to ICQ new family server."); - // we want the handler to be called even if the connecting failed - else if (bServerSSL) { /* Start SSL session if requested */ - debugLogA("(%p) Starting SSL negotiation", Netlib_GetSocket(hConnection)); - - if (!Netlib_StartSsl(hConnection, nullptr)) { - debugLogA("Unable to connect to ICQ new family server, SSL could not be negotiated"); - NetLib_CloseConnection(&hConnection, FALSE); - } - } - - (this->*pCookieData->familyHandler)(hConnection, pCookie, wCookieLen); - - // Free allocated memory - // NOTE: "cookie" will get freed when we have connected to the avatar server. - disposeChain(&pChain); - SAFE_FREE(&pServer); - SAFE_FREE((void**)&pCookieData); - break; - } - - case ICQ_SERVER_EXTSTATUS: // our session data - debugLogA("Received owner session data."); - - while (wBufferLength > 4) { // loop thru all items - WORD itemType = pBuffer[0] * 0x10 | pBuffer[1]; - BYTE itemFlags = pBuffer[2]; - size_t itemLen = pBuffer[3]; - - if (itemType == AVATAR_HASH_PHOTO) { /// TODO: handle photo item - // skip photo item - debugLogA("Photo item recognized"); - } - else if ((itemType == AVATAR_HASH_STATIC || itemType == AVATAR_HASH_FLASH) && (itemLen >= 0x10)) { - debugLogA("Avatar item recognized"); - - if (m_bAvatarsEnabled && !info->bMyAvatarInited) { // signal the server after login - // this refreshes avatar state - it used to work automatically, but now it does not - if (getByte("ForceOurAvatar", 0)) { // keep our avatar - wchar_t *file = GetOwnAvatarFileName(); - SetMyAvatar(0, (LPARAM)file); - SAFE_FREE(&file); - } - else { // only change avatar hash to the same one - BYTE hash[0x14]; - memcpy(hash, pBuffer, 0x14); - hash[2] = 1; // update image status - updateServAvatarHash(hash, 0x14); - } - info->bMyAvatarInited = true; - break; - } - // process owner avatar hash changed notification - handleAvatarOwnerHash(itemFlags, pBuffer, itemLen + 4); - } - else if (itemType == 0x02) { - debugLogA("Status message item recognized"); - } - else if (itemType == 0x0E) { - debugLogA("Status mood item recognized"); - } - - // move to next item - if (wBufferLength >= itemLen + 4) { - wBufferLength -= itemLen + 4; - pBuffer += itemLen + 4; - } - else { - pBuffer += wBufferLength; - wBufferLength = 0; - } - } - break; - - case ICQ_ERROR: // Something went wrong, probably the request for avatar family failed - { - WORD wError; - if (wBufferLength >= 2) - unpackWord(&pBuffer, &wError); - else - wError = 0; - - LogFamilyError(ICQ_SERVICE_FAMILY, wError); - } - break; - - // Stuff we don't care about - case ICQ_SERVER_MOTD: - debugLogA("Server message of the day"); - break; - - default: - debugLogA("Warning: Ignoring SNAC(x%02x,x%02x) - Unknown SNAC (Flags: %u, Ref: %u)", ICQ_SERVICE_FAMILY, pSnacHeader->wSubtype, pSnacHeader->wFlags, pSnacHeader->dwRef); - break; - } -} - - -char* CIcqProto::buildUinList(int subtype, size_t wMaxLen, MCONTACT *hContactResume) -{ - MCONTACT hContact; - WORD wCurrentLen = 0; - int add; - - char *szList = (char*)SAFE_MALLOC(db_get_contact_count() * UINMAXLEN); - - char szLen[2]; - szLen[1] = '\0'; - - if (*hContactResume) - hContact = *hContactResume; - else - hContact = db_find_first(m_szModuleName); - - while (hContact != NULL) { - DWORD dwUIN; - uid_str szUID; - if (!getContactUid(hContact, &dwUIN, &szUID)) { - szLen[0] = (char)mir_strlen(strUID(dwUIN, szUID)); - - switch (subtype) { - case BUL_VISIBLE: - add = ID_STATUS_ONLINE == getWord(hContact, "ApparentMode", 0); - break; - - case BUL_INVISIBLE: - add = ID_STATUS_OFFLINE == getWord(hContact, "ApparentMode", 0); - break; - - case BUL_TEMPVISIBLE: - add = getByte(hContact, "TemporaryVisible", 0); - // clear temporary flag - // Here we assume that all temporary contacts will be in one packet - setByte(hContact, "TemporaryVisible", 0); - break; - - default: - add = 1; - - // If we are in SS mode, we only add those contacts that are - // not in our SS list, or are awaiting authorization, to our - // client side list - if (m_bSsiEnabled && getWord(hContact, DBSETTING_SERVLIST_ID, 0) && - !getByte(hContact, "Auth", 0)) - add = 0; - - // Never add hidden contacts to CS list - if (db_get_b(hContact, "CList", "Hidden", 0)) - add = 0; - - break; - } - - if (add) { - wCurrentLen += szLen[0] + 1; - if (wCurrentLen > wMaxLen) { - *hContactResume = hContact; - return szList; - } - - mir_strcat(szList, szLen); - mir_strcat(szList, szUID); - } - } - - hContact = db_find_next(hContact, m_szModuleName); - } - *hContactResume = NULL; - - return szList; -} - -void CIcqProto::sendEntireListServ(WORD wFamily, WORD wSubtype, int listType) -{ - MCONTACT hResumeContact = NULL; - - do { // server doesn't seem to be able to cope with packets larger than 8k - // send only about 100contacts per packet - char *szList = buildUinList(listType, 0x3E8, &hResumeContact); - - size_t nListLen = mir_strlen(szList); - if (nListLen) { - icq_packet packet; - serverPacketInit(&packet, nListLen + 10); - packFNACHeader(&packet, wFamily, wSubtype); - packBuffer(&packet, (LPBYTE)szList, nListLen); - sendServPacket(&packet); - } - - SAFE_FREE((void**)&szList); - } while (hResumeContact); -} - - -static void packShortCapability(icq_packet *packet, WORD wCapability) -{ - // pack standard capability - DWORD dwQ1 = 0x09460000 | wCapability; - - packDWord(packet, dwQ1); - packDWord(packet, 0x4c7f11d1); - packDWord(packet, 0x82224445); - packDWord(packet, 0x53540000); -} - -// CLI_SETUSERINFO -void CIcqProto::setUserInfo() -{ - icq_packet packet; - size_t wAdditionalData = 0; - BYTE bXStatus = getContactXStatus(NULL); - - wAdditionalData += 16; // MTN - wAdditionalData += 16; // symbol ids - wAdditionalData += 16; // unicode - wAdditionalData += 16; // new caps - wAdditionalData += 16; // xtraz - wAdditionalData += 16; // oscar file transfers - - if (m_bAvatarsEnabled) - wAdditionalData += 16; - if (m_bXStatusEnabled && bXStatus != 0) - wAdditionalData += 16; - wAdditionalData += 16; // html - wAdditionalData += 16; // string user id support - - wAdditionalData += CustomCapList.getCount() * 16; - - //MIM/PackName - bool bHasPackName = false; - DBVARIANT dbv; - if (!db_get_s(0, "ICQCaps", "PackName", &dbv)) { - //MIM/PackName - bHasPackName = true; - wAdditionalData += 16; - } - - serverPacketInit(&packet, 62 + wAdditionalData); - packFNACHeader(&packet, ICQ_LOCATION_FAMILY, ICQ_LOCATION_SET_USER_INFO); - - /* TLV(5): capability data */ - packWord(&packet, 0x0005); - packWord(&packet, WORD(48 + wAdditionalData)); - - packDWord(&packet, 0x563FC809); // CAP_TYPING - packDWord(&packet, 0x0B6F41BD); - packDWord(&packet, 0x9F794226); - packDWord(&packet, 0x09DFA2F3); - - packShortCapability(&packet, 0x1349); // AIM_CAPS_ICQSERVERRELAY - - // Broadcasts the capability to receive UTF8 encoded messages - packShortCapability(&packet, 0x134E); // CAP_UTF8MSGS - - // Tells server we understand to new format of caps - packShortCapability(&packet, 0x0000); // CAP_SHORTCAPS - - packDWord(&packet, 0x1a093c6c); // CAP_XTRAZ - packDWord(&packet, 0xd7fd4ec5); // Broadcasts the capability to handle - packDWord(&packet, 0x9d51a647); // Xtraz - packDWord(&packet, 0x4e34f5a0); - - if (m_bAvatarsEnabled) - packShortCapability(&packet, 0x134C); // CAP_DEVILS - - // Broadcasts the capability to receive Oscar File Transfers - packShortCapability(&packet, 0x1343); // CAP_AIM_FILE - - // Tells the server we can speak to AIM - packShortCapability(&packet, 0x134D); // CAP_AIM_COMPATIBLE - packShortCapability(&packet, 0x134B); // CAP_SENDBUDDYLIST - - if (m_bXStatusEnabled && bXStatus != 0) - packBuffer(&packet, capXStatus[bXStatus - 1], BINARY_CAP_SIZE); - - packShortCapability(&packet, 0x1344); // CAP_ICQDIRECT - packShortCapability(&packet, 0x0002); // CAP_HTMLMSGS - - packDWord(&packet, 0x4D697261); // Miranda Signature - packDWord(&packet, 0x6E64614E); - - MFileVersion v; - Miranda_GetFileVersion(&v); - packWord(&packet, v[0]); - packWord(&packet, v[1]); - packWord(&packet, v[2]); - packWord(&packet, v[3]); - - //MIM/PackName - if (bHasPackName) { - packBuffer(&packet, (BYTE*)dbv.pszVal, 0x10); - db_free(&dbv); - } - - for (auto &it : CustomCapList) - packBuffer(&packet, (PBYTE)it->caps, 0x10); - - sendServPacket(&packet); -} - - -void CIcqProto::handleServUINSettings(int nPort, serverthread_info *info) -{ - setUserInfo(); - - /* SNAC 3,4: Tell server who's on our list (deprecated) */ - /* SNAC 3,15: Try to add unauthorised contacts to temporary list */ - sendEntireListServ(ICQ_BUDDY_FAMILY, ICQ_USER_ADDTOTEMPLIST, BUL_ALLCONTACTS); - - if (m_iDesiredStatus == ID_STATUS_INVISIBLE) { - /* Tell server who's on our visible list (deprecated) */ - if (!m_bSsiEnabled) - sendEntireListServ(ICQ_BOS_FAMILY, ICQ_CLI_ADDVISIBLE, BUL_VISIBLE); - else - updateServVisibilityCode(3); - } - - if (m_iDesiredStatus != ID_STATUS_INVISIBLE) { - /* Tell server who's on our invisible list (deprecated) */ - if (!m_bSsiEnabled) - sendEntireListServ(ICQ_BOS_FAMILY, ICQ_CLI_ADDINVISIBLE, BUL_INVISIBLE); - else - updateServVisibilityCode(4); - } - - // SNAC 1,1E: Set status - icq_packet packet; - { - DWORD dwDirectCookie = rand() ^ (rand() << 16); - - // Get status - WORD wStatus = MirandaStatusToIcq(m_iDesiredStatus); - - // Get status note & mood - char *szStatusNote = PrepareStatusNote(m_iDesiredStatus); - BYTE bXStatus = getContactXStatus(NULL); - char szMoodData[32]; - - // prepare mood id - if (m_bMoodsEnabled && bXStatus && moodXStatus[bXStatus - 1] != -1) - mir_snprintf(szMoodData, "icqmood%d", moodXStatus[bXStatus - 1]); - else - szMoodData[0] = '\0'; - - //! Tricky code, this ensures that the status note will be saved to the directory - SetStatusNote(szStatusNote, m_bGatewayMode ? 5000 : 2500, TRUE); - - size_t wStatusNoteLen = mir_strlen(szStatusNote); - size_t wStatusMoodLen = mir_strlen(szMoodData); - size_t wSessionDataLen = (wStatusNoteLen ? wStatusNoteLen + 4 : 0) + 4 + wStatusMoodLen + 4; - - serverPacketInit(&packet, 71 + (wSessionDataLen ? wSessionDataLen + 4 : 0)); - packFNACHeader(&packet, ICQ_SERVICE_FAMILY, ICQ_CLIENT_SET_STATUS); - packDWord(&packet, 0x00060004); // TLV 6: Status mode and security flags - packWord(&packet, GetMyStatusFlags()); // Status flags - packWord(&packet, wStatus); // Status - packTLVWord(&packet, 0x0008, 0x0A06); // TLV 8: Independent Status Messages - packDWord(&packet, 0x000c0025); // TLV C: Direct connection info - packDWord(&packet, getDword("RealIP", 0)); - packDWord(&packet, nPort); - packByte(&packet, DC_TYPE); // TCP/FLAG firewall settings - packWord(&packet, ICQ_VERSION); - packDWord(&packet, dwDirectCookie); // DC Cookie - packDWord(&packet, WEBFRONTPORT); // Web front port - packDWord(&packet, CLIENTFEATURES); // Client features - packDWord(&packet, 0x7fffffff); // Abused timestamp - packDWord(&packet, ICQ_PLUG_VERSION); // Abused timestamp - if (ServiceExists("SecureIM/IsContactSecured")) - packDWord(&packet, 0x5AFEC0DE); // SecureIM Abuse - else - packDWord(&packet, 0x00000000); // Timestamp - packWord(&packet, 0x0000); // Unknown - packTLVWord(&packet, 0x001F, 0x0000); - - if (wSessionDataLen) { // Pack session data - packWord(&packet, 0x1D); // TLV 1D - packWord(&packet, WORD(wSessionDataLen)); // TLV length - packWord(&packet, 0x02); // Item Type - if (wStatusNoteLen) { - packWord(&packet, 0x400 | WORD(wStatusNoteLen + 4)); // Flags + Item Length - packWord(&packet, WORD(wStatusNoteLen)); // Text Length - packBuffer(&packet, (LPBYTE)szStatusNote, wStatusNoteLen); - packWord(&packet, 0); // Encoding not specified (utf-8 is default) - } - else - packWord(&packet, 0); // Flags + Item Length - packWord(&packet, 0x0E); // Item Type - packWord(&packet, WORD(wStatusMoodLen)); // Flags + Item Length - if (wStatusMoodLen) - packBuffer(&packet, (LPBYTE)szMoodData, wStatusMoodLen); // Mood - - // Save current status note & mood - db_set_utf(NULL, m_szModuleName, DBSETTING_STATUS_NOTE, szStatusNote); - setString(DBSETTING_STATUS_MOOD, szMoodData); - } - // Release memory - SAFE_FREE(&szStatusNote); - - sendServPacket(&packet); - } - - /* SNAC 1,11 */ - serverPacketInit(&packet, 14); - packFNACHeader(&packet, ICQ_SERVICE_FAMILY, ICQ_CLIENT_SET_IDLE); - packDWord(&packet, 0x00000000); - - sendServPacket(&packet); - m_bIdleMode = false; - - // Change status - SetCurrentStatus(m_iDesiredStatus); - - // Finish Login sequence - serverPacketInit(&packet, 98); - packFNACHeader(&packet, ICQ_SERVICE_FAMILY, ICQ_CLIENT_READY); - packDWord(&packet, 0x00220001); // imitate ICQ 6 behaviour - packDWord(&packet, 0x0110164f); - packDWord(&packet, 0x00010004); - packDWord(&packet, 0x0110164f); - packDWord(&packet, 0x00130004); - packDWord(&packet, 0x0110164f); - packDWord(&packet, 0x00020001); - packDWord(&packet, 0x0110164f); - packDWord(&packet, 0x00030001); - packDWord(&packet, 0x0110164f); - packDWord(&packet, 0x00150001); - packDWord(&packet, 0x0110164f); - packDWord(&packet, 0x00040001); - packDWord(&packet, 0x0110164f); - packDWord(&packet, 0x00060001); - packDWord(&packet, 0x0110164f); - packDWord(&packet, 0x00090001); - packDWord(&packet, 0x0110164f); - packDWord(&packet, 0x000A0001); - packDWord(&packet, 0x0110164f); - packDWord(&packet, 0x000B0001); - packDWord(&packet, 0x0110164f); - - sendServPacket(&packet); - - debugLogA(" *** Yeehah, login sequence complete"); - - // login sequence is complete enter logged-in mode - info->bLoggedIn = true; - m_bConnectionLost = false; - - // enable auto info-update routine - icq_EnableUserLookup(true); - - if (!info->isMigrating) { - // Get Offline Messages Reqeust - cookie_offline_messages *ack = (cookie_offline_messages*)SAFE_MALLOC(sizeof(cookie_offline_messages)); - if (ack) { - DWORD dwCookie = AllocateCookie(CKT_OFFLINEMESSAGE, ICQ_MSG_CLI_REQ_OFFLINE, 0, ack); - - serverPacketInit(&packet, 10); - packFNACHeader(&packet, ICQ_MSG_FAMILY, ICQ_MSG_CLI_REQ_OFFLINE, 0, dwCookie); - - sendServPacket(&packet); - } - else icq_LogMessage(LOG_WARNING, LPGEN("Failed to request offline messages. They may be received next time you log in.")); - - // Update our information from the server - sendOwnerInfoRequest(); - - // Request info updates on all contacts - icq_RescanInfoUpdate(); - - // Start sending Keep-Alive packets - StartKeepAlive(info); - - if (m_bAvatarsEnabled) { // Send SNAC 1,4 - request avatar family 0x10 connection - icq_requestnewfamily(ICQ_AVATAR_FAMILY, &CIcqProto::StartAvatarThread); - - m_avatarsConnectionPending = TRUE; - debugLogA("Requesting Avatar family entry point."); - } - - // Set last xstatus - updateServerCustomStatus(TRUE); - } - info->isMigrating = false; - - mir_cslock l(m_modeMsgsMutex); - char **szAwayMsg = MirandaStatusToAwayMsg(m_iStatus); - if (szAwayMsg) - icq_sendSetAimAwayMsgServ(*szAwayMsg); -} diff --git a/protocols/IcqOscarJ/src/fam_02location.cpp b/protocols/IcqOscarJ/src/fam_02location.cpp deleted file mode 100644 index d870eed20a..0000000000 --- a/protocols/IcqOscarJ/src/fam_02location.cpp +++ /dev/null @@ -1,257 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// Handles packets from Location family -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -extern const char* cliSpamBot; - -void CIcqProto::handleLocationFam(BYTE *pBuffer, size_t wBufferLength, snac_header *pSnacHeader) -{ - switch (pSnacHeader->wSubtype) { - case ICQ_LOCATION_RIGHTS_REPLY: // Reply to CLI_REQLOCATION - debugLogA("Server sent SNAC(x02,x03) - SRV_LOCATION_RIGHTS_REPLY"); - break; - - case ICQ_LOCATION_USR_INFO_REPLY: // AIM user info reply - handleLocationUserInfoReply(pBuffer, wBufferLength, pSnacHeader->dwRef); - break; - - case ICQ_ERROR: - { - WORD wError; - if (wBufferLength >= 2) - unpackWord(&pBuffer, &wError); - else - wError = 0; - - if (wError == 4) { - MCONTACT hCookieContact; - cookie_fam15_data *pCookieData; - if (FindCookie(pSnacHeader->dwRef, &hCookieContact, (void**)&pCookieData) && !getContactUin(hCookieContact) && pCookieData->bRequestType == REQUESTTYPE_PROFILE) { - ProtoBroadcastAck(hCookieContact, ACKTYPE_GETINFO, ACKRESULT_FAILED, (HANDLE)1, 0); - ReleaseCookie(pSnacHeader->dwRef); - } - } - - LogFamilyError(ICQ_LOCATION_FAMILY, wError); - break; - } - - default: - debugLogA("Warning: Ignoring SNAC(x%02x,x%02x) - Unknown SNAC (Flags: %u, Ref: %u)", ICQ_LOCATION_FAMILY, pSnacHeader->wSubtype, pSnacHeader->wFlags, pSnacHeader->dwRef); - break; - } -} - -static char* AimApplyEncoding(char* pszStr, const char* pszEncoding) -{ - // decode encoding to ANSI only - if (pszStr && pszEncoding) { - const char *szEnc = strstrnull(pszEncoding, "charset="); - if (szEnc) { // decode custom encoding to Utf-8 - char *szStr = ApplyEncoding(pszStr, szEnc + 9); - // decode utf-8 to ansi - char *szRes = nullptr; - - SAFE_FREE((void**)&pszStr); - if (!utf8_decode(szStr, &szRes)) - szRes = _strdup(szStr); // Legacy fix - SAFE_FREE((void**)&szStr); - - return szRes; - } - } - return pszStr; -} - -void CIcqProto::handleLocationUserInfoReply(BYTE* buf, size_t wLen, DWORD dwCookie) -{ - DWORD dwUIN; - uid_str szUID; - WORD wTLVCount; - WORD wWarningLevel; - WORD status; - cookie_message_data *pCookieData; - - // Unpack the sender's user ID - if (!unpackUID(&buf, &wLen, &dwUIN, &szUID)) return; - - // Syntax check - if (wLen < 4) - return; - - // Warning level? - unpackWord(&buf, &wWarningLevel); - wLen -= 2; - - // TLV count - unpackWord(&buf, &wTLVCount); - wLen -= 2; - - // Determine contact - MCONTACT hContact = HContactFromUID(dwUIN, szUID, nullptr); - - // Ignore away status if the user is not already on our list - if (hContact == INVALID_CONTACT_ID) { - debugLogA("Ignoring away reply (%s)", strUID(dwUIN, szUID)); - return; - } - - MCONTACT hCookieContact; - if (!FindCookie(dwCookie, &hCookieContact, (void**)&pCookieData)) { - debugLogA("Error: Received unexpected away reply from %s", strUID(dwUIN, szUID)); - return; - } - - if (hContact != hCookieContact) { - debugLogA("Error: Away reply Contact does not match Cookie Contact(0x%x != 0x%x)", hContact, hCookieContact); - - ReleaseCookie(dwCookie); // This could be a bad idea, but I think it is safe - return; - } - - switch (GetCookieType(dwCookie)) { - case CKT_FAMILYSPECIAL: - ReleaseCookie(dwCookie); - { - // Syntax check - if (wLen < 4) - return; - - char *szMsg = nullptr; - BYTE *tmp = buf; - - // Get general chain - oscar_tlv_chain* pChain; - if (!(pChain = readIntoTLVChain(&buf, wLen, wTLVCount))) - return; - - disposeChain(&pChain); - - wLen -= (buf - tmp); - - // Get extra chain - if (pChain = readIntoTLVChain(&buf, wLen, 2)) { - char *szEncoding = nullptr; - - // Get Profile encoding TLV - oscar_tlv *pTLV = pChain->getTLV(0x05, 1); - if (pTLV && pTLV->wLen > 0) // store client capabilities - db_set_blob(hContact, m_szModuleName, "CapBuf", pTLV->pData, pTLV->wLen); - else - delSetting(hContact, "CapBuf"); - - pTLV = pChain->getTLV(0x01, 1); - if (pTLV && (pTLV->wLen >= 1)) { - szEncoding = (char*)_alloca(pTLV->wLen + 1); - memcpy(szEncoding, pTLV->pData, pTLV->wLen); - szEncoding[pTLV->wLen] = '\0'; - } - // Get Profile info TLV - pTLV = pChain->getTLV(0x02, 1); - if (pTLV && (pTLV->wLen >= 1)) { - szMsg = (char*)SAFE_MALLOC(pTLV->wLen + 2); - memcpy(szMsg, pTLV->pData, pTLV->wLen); - szMsg[pTLV->wLen] = '\0'; - szMsg[pTLV->wLen + 1] = '\0'; - szMsg = AimApplyEncoding(szMsg, szEncoding); - szMsg = EliminateHtml(szMsg, pTLV->wLen); - } - // Free TLV chain - disposeChain(&pChain); - } - - setString(hContact, "About", szMsg); - ProtoBroadcastAck(hContact, ACKTYPE_GETINFO, ACKRESULT_SUCCESS, (HANDLE)1, 0); - - SAFE_FREE((void**)&szMsg); - } - break; - - default: // away message - status = AwayMsgTypeToStatus(pCookieData->nAckType); - if (status == ID_STATUS_OFFLINE) { - debugLogA("SNAC(2.6) Ignoring unknown status message from %s", strUID(dwUIN, szUID)); - - ReleaseCookie(dwCookie); - return; - } - - ReleaseCookie(dwCookie); - - // Syntax check - if (wLen < 4) - return; - - BYTE *tmp = buf; - - // Get general chain - oscar_tlv_chain* pChain; - if (!(pChain = readIntoTLVChain(&buf, wLen, wTLVCount))) - return; - - disposeChain(&pChain); - - wLen -= (buf - tmp); - - // Get extra chain - char *szMsg = nullptr; - if (pChain = readIntoTLVChain(&buf, wLen, 2)) { - char *szEncoding = nullptr; - - // Get Away encoding TLV - oscar_tlv *pTLV = pChain->getTLV(0x03, 1); - if (pTLV && (pTLV->wLen >= 1)) { - szEncoding = (char*)_alloca(pTLV->wLen + 1); - memcpy(szEncoding, pTLV->pData, pTLV->wLen); - szEncoding[pTLV->wLen] = '\0'; - } - // Get Away info TLV - pTLV = pChain->getTLV(0x04, 1); - if (pTLV && (pTLV->wLen >= 1)) { - szMsg = (char*)SAFE_MALLOC(pTLV->wLen + 2); - memcpy(szMsg, pTLV->pData, pTLV->wLen); - szMsg[pTLV->wLen] = '\0'; - szMsg[pTLV->wLen + 1] = '\0'; - szMsg = AimApplyEncoding(szMsg, szEncoding); - szMsg = EliminateHtml(szMsg, pTLV->wLen); - } - // Free TLV chain - disposeChain(&pChain); - } - - PROTORECVEVENT pre = { 0 }; - pre.szMessage = szMsg ? szMsg : (char *)""; - pre.timestamp = time(0); - pre.lParam = dwCookie; - ProtoChainRecv(hContact, PSR_AWAYMSG, status, (LPARAM)&pre); - - SAFE_FREE((void**)&szMsg); - } -} diff --git a/protocols/IcqOscarJ/src/fam_03buddy.cpp b/protocols/IcqOscarJ/src/fam_03buddy.cpp deleted file mode 100644 index f2d52509fc..0000000000 --- a/protocols/IcqOscarJ/src/fam_03buddy.cpp +++ /dev/null @@ -1,716 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// Handles packets from Buddy family -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -extern const char* cliSpamBot; - -void CIcqProto::handleBuddyFam(BYTE *pBuffer, size_t wBufferLength, snac_header *pSnacHeader, serverthread_info *info) -{ - switch (pSnacHeader->wSubtype) { - case ICQ_USER_ONLINE: - handleUserOnline(pBuffer, wBufferLength, info); - break; - - case ICQ_USER_OFFLINE: - handleUserOffline(pBuffer, wBufferLength); - break; - - case ICQ_USER_SRV_REPLYBUDDY: - handleReplyBuddy(pBuffer, wBufferLength); - break; - - case ICQ_USER_NOTIFY_REJECTED: - handleNotifyRejected(pBuffer, wBufferLength); - break; - - case ICQ_ERROR: - { - WORD wError; - - if (wBufferLength >= 2) - unpackWord(&pBuffer, &wError); - else - wError = 0; - - LogFamilyError(ICQ_BUDDY_FAMILY, wError); - } - break; - - default: - debugLogA("Warning: Ignoring SNAC(x%02x,x%02x) - Unknown SNAC (Flags: %u, Ref: %u)", ICQ_BUDDY_FAMILY, pSnacHeader->wSubtype, pSnacHeader->wFlags, pSnacHeader->dwRef); - break; - } -} - -void CIcqProto::handleReplyBuddy(BYTE *buf, size_t wPackLen) -{ - oscar_tlv_chain *pChain = readIntoTLVChain(&buf, wPackLen, 0); - if (pChain) { - DWORD wMaxUins = pChain->getWord(1, 1); - DWORD wMaxWatchers = pChain->getWord(2, 1); - DWORD wMaxTemporary = pChain->getWord(4, 1); - - debugLogA("MaxUINs %u", wMaxUins); - debugLogA("MaxWatchers %u", wMaxWatchers); - debugLogA("MaxTemporary %u", wMaxTemporary); - - disposeChain(&pChain); - } - else debugLogA("Error: Malformed BuddyReply"); -} - -int unpackSessionDataItem(oscar_tlv_chain *pChain, WORD wItemType, BYTE **ppItemData, WORD *pwItemSize, BYTE *pbItemFlags) -{ - int len = 0; - BYTE *data; - - oscar_tlv *tlv = pChain->getTLV(0x1D, 1); - if (tlv) { - len = tlv->wLen; - data = tlv->pData; - } - - while (len >= 4) { - // parse session data items one by one - WORD itemType; - BYTE itemFlags, itemLen; - - unpackWord(&data, &itemType); - unpackByte(&data, &itemFlags); - unpackByte(&data, &itemLen); - len -= 4; - - // just some validity check - if (itemLen > len) - itemLen = len; - - if (itemType == wItemType) { - // found the requested item - if (ppItemData) - *ppItemData = data; - if (pwItemSize) - *pwItemSize = itemLen; - if (pbItemFlags) - *pbItemFlags = itemFlags; - - return 1; // Success - } - data += itemLen; - len -= itemLen; - } - return 0; -} - - -// TLV(1) User class -// TLV(3) Signon time -// TLV(4) Idle time (in minutes) -// TLV(5) Member since -// TLV(6) New status -// TLV(8) Status Capabilities -// TLV(A) External IP -// TLV(C) DC Info -// TLV(D) Capabilities -// TLV(F) Session timer (in seconds) -// TLV(14) Instance number (AIM only) -// TLV(19) Short capabilities -// TLV(1D) Session Data (Avatar, Mood, etc.) -// TLV(1F) User class (upper bytes) -// TLV(26) AIM Profile update time -// TLV(27) AIM Away message update time -// TLV(29) Away status since -// TLV(2B) URL to protocol icon -// TLV(2F) unknown key -// TLV(30) unknown timestamp - -void CIcqProto::handleUserOnline(BYTE *buf, size_t wLen, serverthread_info*) -{ - DWORD dwPort = 0; - DWORD dwRealIP = 0; - DWORD dwUIN; - uid_str szUID; - DWORD dwDirectConnCookie = 0; - DWORD dwWebPort = 0; - DWORD dwFT1 = 0, dwFT2 = 0, dwFT3 = 0; - const char *szClient = nullptr; - BYTE bClientId = 0; - WORD wVersion = 0; - WORD wTLVCount; - WORD wWarningLevel; - WORD wStatusFlags; - WORD wStatus = 0, wOldStatus = 0; - BYTE nTCPFlag = 0; - char szStrBuf[MAX_PATH]; - - // Unpack the sender's user ID - if (!unpackUID(&buf, &wLen, &dwUIN, &szUID)) - return; - - // Syntax check - if (wLen < 4) - return; - - // Warning level? - unpackWord(&buf, &wWarningLevel); - wLen -= 2; - - // TLV count - unpackWord(&buf, &wTLVCount); - wLen -= 2; - - // Ignore status notification if the user is not already on our list - MCONTACT hContact = HContactFromUID(dwUIN, szUID, nullptr); - if (hContact == INVALID_CONTACT_ID) { - debugLogA("Ignoring user online (%s)", strUID(dwUIN, szUID)); - return; - } - - // Read user info TLVs - oscar_tlv_chain *pChain; - oscar_tlv *pTLV; - - // Syntax check - if (wLen < 4) - return; - - // Get chain - if (!(pChain = readIntoTLVChain(&buf, wLen, wTLVCount))) - return; - - // Get Class word - WORD wClass = pChain->getWord(0x01, 1); - int nIsICQ = wClass & CLASS_ICQ; - - if (dwUIN) { - // Get DC info TLV - pTLV = pChain->getTLV(0x0C, 1); - if (pTLV && (pTLV->wLen >= 15)) { - BYTE *pBuffer = pTLV->pData; - - nIsICQ = TRUE; - - unpackDWord(&pBuffer, &dwRealIP); - unpackDWord(&pBuffer, &dwPort); - unpackByte(&pBuffer, &nTCPFlag); - unpackWord(&pBuffer, &wVersion); - unpackDWord(&pBuffer, &dwDirectConnCookie); - unpackDWord(&pBuffer, &dwWebPort); // Web front port - pBuffer += 4; // Client features - - // Get faked time signatures, used to identify clients - if (pTLV->wLen >= 0x23) { - unpackDWord(&pBuffer, &dwFT1); - unpackDWord(&pBuffer, &dwFT2); - unpackDWord(&pBuffer, &dwFT3); - } - } - - // Get Status info TLV - pTLV = pChain->getTLV(0x06, 1); - if (pTLV && (pTLV->wLen >= 4)) { - BYTE *pBuffer = pTLV->pData; - unpackWord(&pBuffer, &wStatusFlags); - unpackWord(&pBuffer, &wStatus); - } - else if (!nIsICQ) { - // Connected thru AIM client, guess by user class - if (wClass & CLASS_AWAY) - wStatus = ID_STATUS_AWAY; - else if (wClass & CLASS_WIRELESS) - wStatus = ID_STATUS_ONTHEPHONE; - else - wStatus = ID_STATUS_ONLINE; - - wStatusFlags = 0; - } - else { - // Huh? No status TLV? Lets guess then... - wStatusFlags = 0; - wStatus = ICQ_STATUS_ONLINE; - } - } - else { - nIsICQ = FALSE; - - if (wClass & CLASS_AWAY) - wStatus = ID_STATUS_AWAY; - else if (wClass & CLASS_WIRELESS) - wStatus = ID_STATUS_ONTHEPHONE; - else - wStatus = ID_STATUS_ONLINE; - - wStatusFlags = 0; - } - - debugLogA("Flags are %x", wStatusFlags); - debugLogA("Status is %x", wStatus); - - // Get IP TLV - DWORD dwIP = pChain->getDWord(0x0A, 1); - - // Get Online Since TLV - DWORD dwOnlineSince = pChain->getDWord(0x03, 1); - - // Get Away Since TLV - DWORD dwAwaySince = pChain->getDWord(0x29, 1); - - // Get Member Since TLV - DWORD dwMemberSince = pChain->getDWord(0x05, 1); - - // Get Idle timer TLV - WORD wIdleTimer = pChain->getWord(0x04, 1); - time_t tIdleTS = 0; - if (wIdleTimer) { - time(&tIdleTS); - tIdleTS -= (wIdleTimer * 60); - } - - if (wIdleTimer) - debugLogA("Idle timer is %u.", wIdleTimer); - debugLogA("Online since %s", time2text(dwOnlineSince)); - if (dwAwaySince) - debugLogA("Status was set on %s", time2text(dwAwaySince)); - - // Check client capabilities - if (hContact != NULL) { - wOldStatus = getContactStatus(hContact); - - // Collect all Capability info from TLV chain - BYTE *capBuf = nullptr; - WORD capLen = 0; - - // Get Location Capability Info TLVs - oscar_tlv *pFullTLV = pChain->getTLV(0x0D, 1); - oscar_tlv *pShortTLV = pChain->getTLV(0x19, 1); - - if (pFullTLV && (pFullTLV->wLen >= BINARY_CAP_SIZE)) - capLen += pFullTLV->wLen; - - if (pShortTLV && (pShortTLV->wLen >= 2)) - capLen += (pShortTLV->wLen * 8); - - capBuf = (BYTE*)_alloca(capLen + BINARY_CAP_SIZE); - - if (capLen) { - BYTE *pCapability = capBuf; - - capLen = 0; // we need to recount that - - if (pFullTLV && (pFullTLV->wLen >= BINARY_CAP_SIZE)) { - // copy classic Capabilities - BYTE *cData = pFullTLV->pData; - int cLen = pFullTLV->wLen; - - while (cLen) { - // be impervious to duplicates (AOL sends them sometimes) - if (!capLen || !MatchCapability(capBuf, capLen, (capstr*)cData, BINARY_CAP_SIZE)) { - // not present, add - memcpy(pCapability, cData, BINARY_CAP_SIZE); - capLen += BINARY_CAP_SIZE; - pCapability += BINARY_CAP_SIZE; - } - cData += BINARY_CAP_SIZE; - cLen -= BINARY_CAP_SIZE; - } - } - - if (pShortTLV && (pShortTLV->wLen >= 2)) { - // copy short Capabilities - capstr tmp; - BYTE *cData = pShortTLV->pData; - int cLen = pShortTLV->wLen; - - memcpy(tmp, capShortCaps, BINARY_CAP_SIZE); - while (cLen) { - // be impervious to duplicates (AOL sends them sometimes) - tmp[2] = cData[0]; - tmp[3] = cData[1]; - - if (!capLen || !MatchCapability(capBuf, capLen, &tmp, BINARY_CAP_SIZE)) { - // not present, add - memcpy(pCapability, tmp, BINARY_CAP_SIZE); - capLen += BINARY_CAP_SIZE; - pCapability += BINARY_CAP_SIZE; - } - cData += 2; - cLen -= 2; - } - } - debugLogA("Detected %d capability items.", capLen / BINARY_CAP_SIZE); - } - - if (capLen) { -#ifdef _DEBUG - for (WORD i = 0; i < capLen; i += BINARY_CAP_SIZE) { - char tmp[100]; - bin2hex(capBuf + i, BINARY_CAP_SIZE, tmp); - debugLogA("Capability: %s", tmp); - } -#endif - - // Update the contact's capabilies if present in packet - SetCapabilitiesFromBuffer(hContact, capBuf, capLen, wOldStatus == ID_STATUS_OFFLINE); - - char *szCurrentClient = wOldStatus == ID_STATUS_OFFLINE ? nullptr : getSettingStringUtf(hContact, "MirVer", nullptr); - - szClient = detectUserClient(hContact, nIsICQ, wClass, dwOnlineSince, szCurrentClient, wVersion, dwFT1, dwFT2, dwFT3, dwDirectConnCookie, dwWebPort, capBuf, capLen, &bClientId, szStrBuf); - // Check if the client changed, if not do not change - if (szCurrentClient && !mir_strcmp(szCurrentClient, szClient)) - szClient = (const char*)-1; - SAFE_FREE(&szCurrentClient); - } - else if (wOldStatus == ID_STATUS_OFFLINE) { - // Remove the contact's capabilities if coming from offline - ClearAllContactCapabilities(hContact); - - // no capability - debugLogA("No capability info TLVs"); - - szClient = detectUserClient(hContact, nIsICQ, wClass, dwOnlineSince, nullptr, wVersion, dwFT1, dwFT2, dwFT3, dwDirectConnCookie, dwWebPort, nullptr, capLen, &bClientId, szStrBuf); - } - else // Capabilities not present in update packet, do not touch - szClient = (const char*)-1; // we don't want to client be overwritten - - // handle Xtraz status - char *moodData = nullptr; - WORD moodSize = 0; - - unpackSessionDataItem(pChain, 0x0E, (BYTE**)&moodData, &moodSize, nullptr); - if (capLen || wOldStatus == ID_STATUS_OFFLINE) - handleXStatusCaps(dwUIN, szUID, hContact, capBuf, capLen, moodData, moodSize); - else - handleXStatusCaps(dwUIN, szUID, hContact, nullptr, 0, moodData, moodSize); - - // Determine support for extended status messages - if (pChain->getWord(0x08, 1) == 0x0A06) - SetContactCapabilities(hContact, CAPF_STATUS_MESSAGES); - else if (wOldStatus == ID_STATUS_OFFLINE) - ClearContactCapabilities(hContact, CAPF_STATUS_MESSAGES); - - if (wOldStatus == ID_STATUS_OFFLINE) { - if (CheckContactCapabilities(hContact, CAPF_SRV_RELAY)) - debugLogA("Supports advanced messages"); - else - debugLogA("Does NOT support advanced messages"); - } - - if (!nIsICQ) { - // AIM clients does not advertise these, but do support them - SetContactCapabilities(hContact, CAPF_UTF | CAPF_TYPING); - // Server relayed messages are only supported by ICQ clients - ClearContactCapabilities(hContact, CAPF_SRV_RELAY); - - if (dwUIN && wOldStatus == ID_STATUS_OFFLINE) - debugLogA("Logged in with AIM client"); - } - - if (nIsICQ && wVersion < 8) { - ClearContactCapabilities(hContact, CAPF_SRV_RELAY); - if (wOldStatus == ID_STATUS_OFFLINE) - debugLogA("Forcing simple messages due to compability issues"); - } - - // Process Avatar Hash - pTLV = pChain->getTLV(0x1D, 1); - if (pTLV) - handleAvatarContactHash(dwUIN, szUID, hContact, pTLV->pData, pTLV->wLen); - else - handleAvatarContactHash(dwUIN, szUID, hContact, nullptr, 0); - - // Process Status Note - parseStatusNote(dwUIN, szUID, hContact, pChain); - } - // Free TLV chain - disposeChain(&pChain); - - // Save contacts details in database - if (hContact != NULL) { - setDword(hContact, "LogonTS", dwOnlineSince); - setDword(hContact, "AwayTS", dwAwaySince); - setDword(hContact, "IdleTS", tIdleTS); - - if (dwMemberSince) - setDword(hContact, "MemberTS", dwMemberSince); - - if (nIsICQ) { - // on AIM these are not used - setDword(hContact, "DirectCookie", dwDirectConnCookie); - setByte(hContact, "DCType", (BYTE)nTCPFlag); - setWord(hContact, "UserPort", (WORD)(dwPort & 0xffff)); - setWord(hContact, "Version", wVersion); - } - else { - delSetting(hContact, "DirectCookie"); - delSetting(hContact, "DCType"); - delSetting(hContact, "UserPort"); - delSetting(hContact, "Version"); - } - - // if no detection, set uknown - if (!szClient) - szClient = (nIsICQ ? "Unknown" : "Unknown AIM"); - - if (szClient != (char*)-1) { - db_set_utf(hContact, m_szModuleName, "MirVer", szClient); - setByte(hContact, "ClientID", bClientId); - } - - if (wOldStatus == ID_STATUS_OFFLINE) { - setDword(hContact, "IP", dwIP); - setDword(hContact, "RealIP", dwRealIP); - } - else { - // if not first notification only write significant information - if (dwIP) - setDword(hContact, "IP", dwIP); - if (dwRealIP) - setDword(hContact, "RealIP", dwRealIP); - } - setWord(hContact, "Status", (WORD)IcqStatusToMiranda(wStatus)); - - // Update info? - if (dwUIN) { - // check if the local copy of user details is up-to-date - if (IsMetaInfoChanged(hContact)) - icq_QueueUser(hContact); - } - } - - LPCTSTR ptszStatus = Clist_GetStatusModeDescription(IcqStatusToMiranda(wStatus), 0); - if (wOldStatus != IcqStatusToMiranda(wStatus)) { - // And a small log notice... if status was changed - if (nIsICQ) - debugLogA("%u changed status to %S (v%d).", dwUIN, ptszStatus, wVersion); - else - debugLogA("%s changed status to %S.", strUID(dwUIN, szUID), ptszStatus); - } - - if (szClient == cliSpamBot) { - if (getByte("KillSpambots", DEFAULT_KILLSPAM_ENABLED) && db_get_b(hContact, "CList", "NotOnList", 0)) { - // kill spammer - icq_DequeueUser(dwUIN); - icq_sendRemoveContact(dwUIN, nullptr); - AddToSpammerList(dwUIN); - if (getByte("PopupsSpamEnabled", DEFAULT_SPAM_POPUPS_ENABLED)) - ShowPopupMsg(hContact, LPGEN("Spambot Detected"), LPGEN("Contact deleted & further events blocked."), POPTYPE_SPAM); - db_delete_contact(hContact); - - debugLogA("Contact %u deleted", dwUIN); - } - } -} - -void CIcqProto::handleUserOffline(BYTE *buf, size_t wLen) -{ - DWORD dwUIN; - uid_str szUID; - - do { - oscar_tlv_chain *pChain = nullptr; - // Unpack the sender's user ID - if (!unpackUID(&buf, &wLen, &dwUIN, &szUID)) return; - - // Warning level? - buf += 2; - - // TLV Count - WORD wTLVCount; - unpackWord(&buf, &wTLVCount); - wLen -= 4; - - // Skip the TLV chain - DWORD dwAwaySince = 0; - while (wTLVCount && wLen >= 4) { - WORD wTLVType; - WORD wTLVLen; - - unpackWord(&buf, &wTLVType); - unpackWord(&buf, &wTLVLen); - wLen -= 4; - - // stop parsing overflowed packet - if (wTLVLen > wLen) { - disposeChain(&pChain); - return; - } - - if (wTLVType == 0x1D) { - // read only TLV with Session data into chain - BYTE *pTLV = buf - 4; - disposeChain(&pChain); - pChain = readIntoTLVChain(&pTLV, wLen + 4, 1); - } - else if (wTLVType == 0x29 && wTLVLen == sizeof(DWORD)) { - // get Away Since value - BYTE *pData = buf; - unpackDWord(&pData, &dwAwaySince); - } - - buf += wTLVLen; - wLen -= wTLVLen; - wTLVCount--; - } - - // Determine contact - MCONTACT hContact = HContactFromUID(dwUIN, szUID, nullptr); - - // Skip contacts that are not already on our list or are already offline - if (hContact != INVALID_CONTACT_ID) { - WORD wOldStatus = getContactStatus(hContact); - - // Process Avatar Hash - oscar_tlv *pAvatarTLV = pChain ? pChain->getTLV(0x1D, 1) : nullptr; - if (pAvatarTLV) - handleAvatarContactHash(dwUIN, szUID, hContact, pAvatarTLV->pData, pAvatarTLV->wLen); - else - handleAvatarContactHash(dwUIN, szUID, hContact, nullptr, 0); - - // Process Status Note (offline status note) - parseStatusNote(dwUIN, szUID, hContact, pChain); - - // Update status times - setDword(hContact, "IdleTS", 0); - setDword(hContact, "AwayTS", dwAwaySince); - - // Clear custom status & mood - char tmp = NULL; - handleXStatusCaps(dwUIN, szUID, hContact, (BYTE*)&tmp, 0, &tmp, 0); - - if (wOldStatus != ID_STATUS_OFFLINE) { - debugLogA("%s went offline.", strUID(dwUIN, szUID)); - - setWord(hContact, "Status", ID_STATUS_OFFLINE); - // close Direct Connections to that user - CloseContactDirectConns(hContact); - // Reset DC status - setByte(hContact, "DCStatus", 0); - } - else debugLogA("%s is offline.", strUID(dwUIN, szUID)); - } - - // Release memory - disposeChain(&pChain); - } while (wLen >= 1); -} - - -void CIcqProto::parseStatusNote(DWORD dwUin, char *szUid, MCONTACT hContact, oscar_tlv_chain *pChain) -{ - DWORD dwStatusNoteTS = time(0); - BYTE *pStatusNoteTS, *pStatusNote; - WORD wStatusNoteTSLen, wStatusNoteLen; - BYTE bStatusNoteFlags; - - if (unpackSessionDataItem(pChain, 0x0D, &pStatusNoteTS, &wStatusNoteTSLen, nullptr) && wStatusNoteTSLen == sizeof(DWORD)) - unpackDWord(&pStatusNoteTS, &dwStatusNoteTS); - - // Get Status Note session item - if (unpackSessionDataItem(pChain, 0x02, &pStatusNote, &wStatusNoteLen, &bStatusNoteFlags)) { - char *szStatusNote = nullptr; - - if ((bStatusNoteFlags & 4) == 4 && wStatusNoteLen >= 4) { - BYTE *buf = pStatusNote; - WORD buflen = wStatusNoteLen - 2; - WORD wTextLen; - - unpackWord(&buf, &wTextLen); - if (wTextLen > buflen) - wTextLen = buflen; - - if (wTextLen > 0) { - szStatusNote = (char*)_alloca(wStatusNoteLen + 1); - unpackString(&buf, szStatusNote, wTextLen); - szStatusNote[wTextLen] = '\0'; - buflen -= wTextLen; - - WORD wEncodingType = 0; - char *szEncoding = nullptr; - - if (buflen >= 2) - unpackWord(&buf, &wEncodingType); - - if (wEncodingType == 1 && buflen > 6) { - // Encoding specified - buf += 2; - buflen -= 2; - unpackWord(&buf, &wTextLen); - if (wTextLen > buflen) - wTextLen = buflen; - szEncoding = (char*)_alloca(wTextLen + 1); - unpackString(&buf, szEncoding, wTextLen); - szEncoding[wTextLen] = '\0'; - } - else if (UTF8_IsValid(szStatusNote)) - szEncoding = "utf-8"; - - szStatusNote = ApplyEncoding(szStatusNote, szEncoding); - } - } - // Check if the status note was changed - if (dwStatusNoteTS > getDword(hContact, DBSETTING_STATUS_NOTE_TIME, 0)) { - DBVARIANT dbv = { DBVT_DELETED }; - - if (mir_strlen(szStatusNote) || (!getString(hContact, DBSETTING_STATUS_NOTE, &dbv) && (dbv.type == DBVT_ASCIIZ || dbv.type == DBVT_UTF8) && mir_strlen(dbv.pszVal))) - debugLogA("%s changed status note to \"%s\"", strUID(dwUin, szUid), szStatusNote ? szStatusNote : ""); - - db_free(&dbv); - - if (szStatusNote) - db_set_utf(hContact, m_szModuleName, DBSETTING_STATUS_NOTE, szStatusNote); - else - delSetting(hContact, DBSETTING_STATUS_NOTE); - setDword(hContact, DBSETTING_STATUS_NOTE_TIME, dwStatusNoteTS); - - if (getContactXStatus(hContact) != 0 || !CheckContactCapabilities(hContact, CAPF_STATUS_MESSAGES)) { - setStatusMsgVar(hContact, szStatusNote, false); - - wchar_t *tszNote = mir_utf8decodeW(szStatusNote); - ProtoBroadcastAck(hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, nullptr, (LPARAM)tszNote); - mir_free(tszNote); - } - } - SAFE_FREE(&szStatusNote); - } - else if (getContactStatus(hContact) == ID_STATUS_OFFLINE) { - setStatusMsgVar(hContact, nullptr, false); - delSetting(hContact, DBSETTING_STATUS_NOTE); - setDword(hContact, DBSETTING_STATUS_NOTE_TIME, dwStatusNoteTS); - } -} - -void CIcqProto::handleNotifyRejected(BYTE *buf, size_t wPackLen) -{ - DWORD dwUIN; - uid_str szUID; - - while (wPackLen) - if (unpackUID(&buf, &wPackLen, &dwUIN, &szUID)) - debugLogA("%s status notification rejected.", strUID(dwUIN, szUID)); -} diff --git a/protocols/IcqOscarJ/src/fam_04message.cpp b/protocols/IcqOscarJ/src/fam_04message.cpp deleted file mode 100644 index d3de9c94ce..0000000000 --- a/protocols/IcqOscarJ/src/fam_04message.cpp +++ /dev/null @@ -1,2620 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// Handles packets from Family 4 ICBM Messages -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -void CIcqProto::handleMsgFam(BYTE *pBuffer, size_t wBufferLength, snac_header *pSnacHeader) -{ - switch (pSnacHeader->wSubtype) { - case ICQ_MSG_SRV_ERROR: // SNAC(4, 0x01) - handleRecvServMsgError(pBuffer, wBufferLength, pSnacHeader->dwRef); - break; - - case ICQ_MSG_SRV_REPLYICBM: // SNAC(4, 0x05) SRV_REPLYICBM - handleReplyICBM(); - break; - - case ICQ_MSG_SRV_RECV: // SNAC(4, 0x07) - handleRecvServMsg(pBuffer, wBufferLength, pSnacHeader->dwRef); - break; - - case ICQ_MSG_SRV_MISSED_MESSAGE: // SNAC(4, 0x0A) - handleMissedMsg(pBuffer, wBufferLength); - break; - - case ICQ_MSG_RESPONSE: // SNAC(4, 0x0B) - handleRecvMsgResponse(pBuffer, wBufferLength); - break; - - case ICQ_MSG_SRV_ACK: // SNAC(4, 0x0C) Server acknowledgements - handleServerAck(pBuffer, wBufferLength, pSnacHeader->dwRef); - break; - - case ICQ_MSG_MTN: // SNAC(4, 0x14) Typing notifications - handleTypingNotification(pBuffer, wBufferLength); - break; - - case ICQ_MSG_SRV_OFFLINE_REPLY: // SNAC(4, 0x17) Offline Messages response - handleOffineMessagesReply(pSnacHeader->dwRef); - break; - - default: - debugLogA("Warning: Ignoring SNAC(x%02x,x%02x) - Unknown SNAC (Flags: %u, Ref: %u)", ICQ_MSG_FAMILY, pSnacHeader->wSubtype, pSnacHeader->wFlags, pSnacHeader->dwRef); - break; - } -} - -static void setMsgChannelParams(CIcqProto *ppro, WORD wChan, DWORD dwFlags) -{ - icq_packet packet; - - // Set message parameters for channel wChan (CLI_SET_ICBM_PARAMS) - serverPacketInit(&packet, 26); - packFNACHeader(&packet, ICQ_MSG_FAMILY, ICQ_MSG_CLI_SETPARAMS); - packWord(&packet, wChan); // Channel - packDWord(&packet, dwFlags); // Flags - packWord(&packet, MAX_MESSAGESNACSIZE); // Max message snac size - packWord(&packet, 0x03E7); // Max sender warning level - packWord(&packet, 0x03E7); // Max receiver warning level - packWord(&packet, CLIENTRATELIMIT); // Minimum message interval in seconds - packWord(&packet, 0x0000); // Unknown - ppro->sendServPacket(&packet); -} - -void CIcqProto::handleReplyICBM() -{ - // Set message parameters for all channels (imitate ICQ 6) - setMsgChannelParams(this, 0x0000, 0x0000070B); -} - -void CIcqProto::handleRecvServMsg(BYTE *buf, size_t wLen, DWORD dwRef) -{ - DWORD dwUin; - DWORD dwMsgID1; - DWORD dwMsgID2; - WORD wTLVCount; - WORD wMessageFormat; - uid_str szUID; - - if (wLen < 11) { // just do some basic packet checking - debugLogA("Error: Malformed message thru server"); - return; - } - - // These two values are some kind of reference, we need to save - // them to send file request responses for example - unpackLEDWord(&buf, &dwMsgID1); // TODO: msg cookies should be main - wLen -= 4; - unpackLEDWord(&buf, &dwMsgID2); - wLen -= 4; - - // The message type used: - unpackWord(&buf, &wMessageFormat); // 0x0001: Simple message format - wLen -= 2; // 0x0002: Advanced message format - // 0x0004: 'New' message format - // Sender UIN - if (!unpackUID(&buf, &wLen, &dwUin, &szUID)) return; - - if (dwUin && IsOnSpammerList(dwUin)) { - debugLogA("Ignored Message from known Spammer"); - return; - } - - if (wLen < 4) { // just do some basic packet checking - debugLogA("Error: Malformed message thru server"); - return; - } - - // Warning level? - buf += 2; - wLen -= 2; - - // Number of following TLVs, until msg-format dependant TLVs - unpackWord(&buf, &wTLVCount); - wLen -= 2; - if (wTLVCount > 0) { - // Save current buffer pointer so we can calculate - // how much data we have left after the chain read. - BYTE *pBufStart = buf; - oscar_tlv_chain *chain = readIntoTLVChain(&buf, wLen, wTLVCount); - - // This chain contains info that is filled in by the server. - // TLV(1): unknown - // TLV(2): date: on since - // TLV(3): date: on since - // TLV(4): unknown, usually 0000. Not in file-req or auto-msg-req - // TLV(6): sender's status - // TLV(F): a time in seconds, unknown - - disposeChain(&chain); - - // Update wLen - wLen -= buf - pBufStart; - } - - - // This is where the format specific data begins - - switch (wMessageFormat) { - - case 1: // Simple message format - handleRecvServMsgType1(buf, wLen, dwUin, szUID, dwMsgID1, dwRef); - break; - - case 2: // Encapsulated messages - handleRecvServMsgType2(buf, wLen, dwUin, szUID, dwMsgID1, dwMsgID2); - break; - - case 4: // Typed messages - handleRecvServMsgType4(buf, wLen, dwUin, szUID, dwMsgID1, dwMsgID2, dwRef); - break; - - default: - debugLogA("Unknown format message thru server - Ref %u, Type: %u, UID: %s", dwRef, wMessageFormat, strUID(dwUin, szUID)); - break; - } -} - -char* CIcqProto::convertMsgToUserSpecificUtf(MCONTACT hContact, const char *szMsg) -{ - WORD wCP = getWord(hContact, "CodePage", m_wAnsiCodepage); - char *usMsg = nullptr; - - if (wCP != CP_ACP) - usMsg = ansi_to_utf8_codepage(szMsg, wCP); - - return usMsg; -} - -void CIcqProto::handleRecvServMsgType1(BYTE *buf, size_t wLen, DWORD dwUin, char *szUID, DWORD dwMsgID1, DWORD dwRef) -{ - WORD wTLVType; - size_t wTLVLen; - BYTE* pMsgTLV; - - if (wLen < 4) { // just perform basic structure check - debugLogA("Message (format %u) - Ignoring empty message", 1); - return; - } - - // Unpack the first TLV(2) - unpackTypedTLV(buf, wLen, 2, &wTLVType, &wTLVLen, &pMsgTLV); - debugLogA("Message (format %u) - UID: %s", 1, strUID(dwUin, szUID)); - - // It must be TLV(2) - if (wTLVType == 2) { - BYTE *pDataBuf = pMsgTLV; - oscar_tlv_chain *pChain = readIntoTLVChain(&pDataBuf, wTLVLen, 0); - - // TLV(2) contains yet another TLV chain with the following TLVs: - // TLV(1281): Capability - // TLV(257): This TLV contains the actual message (can be fragmented) - - if (pChain) { - // Find the capability TLV - oscar_tlv *pCapabilityTLV = pChain->getTLV(0x0501, 1); - if (pCapabilityTLV && (pCapabilityTLV->wLen > 0)) { - WORD wDataLen = pCapabilityTLV->wLen; - if (wDataLen > 0) - debugLogA("Message (format 1) - Message has %d caps.", wDataLen); - } - else debugLogA("Message (format 1) - No message cap."); - - { - // Parse the message parts, usually only one 0x0101 TLV containing the message, - // but in some cases there can be more 0x0101 TLVs containing message parts in - // different encodings (just like the new format of Offline Messages). - DWORD dwRecvTime; - char* szMsg = nullptr; - bool bUtf8 = false; - PROTORECVEVENT pre = { 0 }; - - int bAdded; - MCONTACT hContact = HContactFromUID(dwUin, szUID, &bAdded); - - WORD wMsgPart = 1; - while (oscar_tlv *pMessageTLV = pChain->getTLV(0x0101, wMsgPart)) { // Loop thru all message parts - if (pMessageTLV->wLen > 4) { - char *szMsgPart = nullptr; - bool bMsgPartUnicode = false; - - // The message begins with a encoding specification - // The first WORD is believed to have the following meaning: - // 0x00: US-ASCII - // 0x02: Unicode UCS-2 Big Endian encoding - // 0x03: local 8bit encoding - BYTE *pMsgBuf = pMessageTLV->pData; - WORD wEncoding, wCodePage; - unpackWord(&pMsgBuf, &wEncoding); - unpackWord(&pMsgBuf, &wCodePage); - - WORD wMsgLen = pMessageTLV->wLen - 4; - debugLogA("Message (format 1) - Part %d: Encoding is 0x%X, page is 0x%X", wMsgPart, wEncoding, wCodePage); - - switch (wEncoding) { - case 2: // UCS-2 - { - WCHAR *usMsgPart = (WCHAR*)SAFE_MALLOC(wMsgLen + 2); - - unpackWideString(&pMsgBuf, usMsgPart, wMsgLen); - usMsgPart[wMsgLen / sizeof(WCHAR)] = 0; - - szMsgPart = make_utf8_string(usMsgPart); - if (!IsUSASCII(szMsgPart, mir_strlen(szMsgPart))) - bMsgPartUnicode = true; - SAFE_FREE(&usMsgPart); - } - break; - - case 0: // us-ascii - case 3: // ANSI - default: - // Copy the message text into a new proper string. - szMsgPart = (char*)SAFE_MALLOC(wMsgLen + 1); - memcpy(szMsgPart, pMsgBuf, wMsgLen); - szMsgPart[wMsgLen] = '\0'; - break; - } - - // Check if the new part is compatible with the message - if (!bUtf8 && bMsgPartUnicode) { // make the resulting message utf-8 encoded - need to append utf-8 encoded part - if (szMsg) { // not necessary to convert - appending first part, only set flags - char *szUtfMsg = ansi_to_utf8_codepage(szMsg, getWord(hContact, "CodePage", m_wAnsiCodepage)); - - SAFE_FREE(&szMsg); - szMsg = szUtfMsg; - } - bUtf8 = true; - } - if (!bMsgPartUnicode && bUtf8) { // convert message part to utf-8 and append - char *szUtfPart = ansi_to_utf8_codepage((char*)szMsgPart, getWord(hContact, "CodePage", m_wAnsiCodepage)); - SAFE_FREE(&szMsgPart); - szMsgPart = szUtfPart; - } - // Append the new message part - szMsg = (char*)SAFE_REALLOC(szMsg, mir_strlen(szMsg) + mir_strlen(szMsgPart) + 1); - - mir_strcat(szMsg, szMsgPart); - SAFE_FREE(&szMsgPart); - } - wMsgPart++; - } - if (mir_strlen(szMsg)) { - if (_strnicmp(szMsg, "", 6) == 0) // strip HTML formating from AIM message - szMsg = EliminateHtml(szMsg, mir_strlen(szMsg)); - - if (!bUtf8 && !IsUSASCII(szMsg, mir_strlen(szMsg))) { // message is Ansi and contains national characters, create Unicode part by codepage - char *usMsg = convertMsgToUserSpecificUtf(hContact, szMsg); - if (usMsg) { - SAFE_FREE(&szMsg); - szMsg = usMsg; - bUtf8 = true; - } - } - - dwRecvTime = (DWORD)time(0); - - { // Check if the message was received as offline - cookie_offline_messages *cookie; - if (!(dwRef & 0x80000000) && FindCookie(dwRef, nullptr, (void**)&cookie)) { - cookie->nMessages++; - - WORD wTimeTLVType; - size_t wTimeTLVLen; - BYTE *pTimeTLV; - unpackTypedTLV(buf, wLen, 0x16, &wTimeTLVType, &wTimeTLVLen, &pTimeTLV); - if (pTimeTLV && wTimeTLVType == 0x16 && wTimeTLVLen == 4) { // found Offline timestamp - BYTE *pBuf = pTimeTLV; - - unpackDWord(&pBuf, &dwRecvTime); - debugLogA("Message (format %u) - Offline timestamp is %s", 1, time2text(dwRecvTime)); - } - SAFE_FREE((void**)&pTimeTLV); - } - } - // Create and send the message event - pre.timestamp = dwRecvTime; - pre.szMessage = (char *)szMsg; - ProtoChainRecvMsg(hContact, &pre); - - debugLogA("Message (format 1) received"); - - // Save tick value - setDword(hContact, "TickTS", time(0) - (dwMsgID1 / 1000)); - } - else debugLogA("Message (format %u) - Ignoring empty message", 1); - - SAFE_FREE(&szMsg); - } - - // Free the chain memory - disposeChain(&pChain); - } - else debugLogA("Failed to read TLV chain in message (format 1)"); - } - else debugLogA("Unsupported TLV (%u) in message (format %u)", wTLVType, 1); - - SAFE_FREE((void**)&pMsgTLV); -} - -void CIcqProto::handleRecvServMsgType2(BYTE *buf, size_t wLen, DWORD dwUin, char *szUID, DWORD dwMsgID1, DWORD dwMsgID2) -{ - WORD wTLVType; - size_t wTLVLen; - BYTE *pDataBuf = nullptr; - - if (wLen < 4) { - debugLogA("Message (format %u) - Ignoring empty message", 2); - return; - } - - // Unpack the first TLV(5) - unpackTypedTLV(buf, wLen, 5, &wTLVType, &wTLVLen, &pDataBuf); - debugLogA("Message (format %u) - UID: %s", 2, strUID(dwUin, szUID)); - BYTE *pBuf = pDataBuf; - - // It must be TLV(5) - if (wTLVType == 5) { - WORD wCommand; - oscar_tlv_chain* chain; - oscar_tlv* tlv; - DWORD q1, q2, q3, q4; - - if (wTLVLen < 26) { // just check if all basic data is there - debugLogA("Message (format %u) - Ignoring empty message", 2); - SAFE_FREE((void**)&pBuf); - return; - } - - unpackWord(&pDataBuf, &wCommand); - wTLVLen -= 2; - - // Command 0x0000 - Normal message/file send request - // 0x0001 - Abort request - // 0x0002 - Acknowledge request - debugLogA("Command is %u", wCommand); - - // Some stuff we don't use - pDataBuf += 8; // dwID1 and dwID2 again - wTLVLen -= 8; - unpackDWord(&pDataBuf, &q1); - unpackDWord(&pDataBuf, &q2); - unpackDWord(&pDataBuf, &q3); - unpackDWord(&pDataBuf, &q4); // Message Capability - wTLVLen -= 16; - - if (CompareGUIDs(q1, q2, q3, q4, MCAP_SRV_RELAY_FMT)) { // we surely have at least 4 bytes for TLV chain - MCONTACT hContact = HContactFromUID(dwUin, szUID, nullptr); - - if (wCommand == 1) { - debugLogA("Cannot handle abort messages yet... :("); - SAFE_FREE((void**)&pBuf); - return; - } - - if (wTLVLen < 4) { // just check if at least one tlv is there - debugLogA("Message (format %u) - Ignoring empty message", 2); - SAFE_FREE((void**)&pBuf); - return; - } - - // This TLV chain may contain the following TLVs: - // TLV(A): Acktype 0x0000 - normal message - // 0x0001 - file request / abort request - // 0x0002 - file ack - // TLV(F): Unknown - // TLV(3): External IP - // TLV(5): DC port (not to use for filetransfers) - // TLV(0x2711): The next message level - - chain = readIntoTLVChain(&pDataBuf, wTLVLen, 0); - if (!chain) { // sanity check - debugLogA("Message (format %u) - Invalid data", 2); - SAFE_FREE((void**)&pBuf); - return; - } - - WORD wAckType = chain->getWord(0x0A, 1); - - // Update the saved DC info (if contact already exists) - if (hContact != INVALID_CONTACT_ID) { - DWORD dwIP, dwExternalIP; - WORD wPort; - - if (dwExternalIP = chain->getDWord(0x03, 1)) - setDword(hContact, "RealIP", dwExternalIP); - if (dwIP = chain->getDWord(0x04, 1)) - setDword(hContact, "IP", dwIP); - if (wPort = chain->getWord(0x05, 1)) - setWord(hContact, "UserPort", wPort); - - // Save tick value - BYTE bClientID = getByte(hContact, "ClientID", 0); - if (bClientID == CLID_GENERIC || bClientID == CLID_ICQ6) - setDword(hContact, "TickTS", time(0) - (dwMsgID1 / 1000)); - else - setDword(hContact, "TickTS", 0); - } - - // Parse the next message level - if (tlv = chain->getTLV(0x2711, 1)) - parseServRelayData(tlv->pData, tlv->wLen, hContact, dwUin, szUID, dwMsgID1, dwMsgID2, wAckType); - else - debugLogA("Warning, no 0x2711 TLV in message (format 2)"); - - // Clean up - disposeChain(&chain); - } - else if (CompareGUIDs(q1, q2, q3, q4, MCAP_REVERSE_DC_REQ)) { // Handle reverse DC request - if (wCommand == 1) { - debugLogA("Cannot handle abort messages yet... :("); - SAFE_FREE((void**)&pBuf); - return; - } - if (wTLVLen < 4) { // just check if at least one tlv is there - debugLogA("Message (format %u) - Ignoring empty message", 2); - SAFE_FREE((void**)&pBuf); - return; - } - if (!dwUin) { // AIM cannot send this, just sanity - debugLogA("Error: Malformed UIN in packet"); - SAFE_FREE((void**)&pBuf); - return; - } - chain = readIntoTLVChain(&pDataBuf, wTLVLen, 0); - if (!chain) { // Malformed packet - debugLogA("Error: Malformed data in packet"); - SAFE_FREE((void**)&pBuf); - return; - } - - // Parse the next message level - if (tlv = chain->getTLV(0x2711, 1)) { - if (tlv->wLen == 0x1B) { - BYTE *buf2 = tlv->pData; - unpackLEDWord(&buf2, &dwUin); - - MCONTACT hContact = HContactFromUIN(dwUin, nullptr); - if (hContact == INVALID_CONTACT_ID) - debugLogA("Error: %s from unknown contact %u", "Reverse Connect Request", dwUin); - else { - DWORD dwIp, dwPort; - WORD wVersion; - BYTE bMode; - - unpackDWord(&buf2, &dwIp); - unpackLEDWord(&buf2, &dwPort); - unpackByte(&buf2, &bMode); - buf2 += 4; // unknown - if (dwPort) - buf2 += 4; // port, again? - else - unpackLEDWord(&buf2, &dwPort); - unpackLEWord(&buf2, &wVersion); - - setDword(hContact, "IP", dwIp); - setWord(hContact, "UserPort", (WORD)dwPort); - setByte(hContact, "DCType", bMode); - setWord(hContact, "Version", wVersion); - if (wVersion > 6) { - cookie_reverse_connect *pCookie = (cookie_reverse_connect*)SAFE_MALLOC(sizeof(cookie_reverse_connect)); - - unpackLEDWord(&buf2, (DWORD*)&pCookie->ft); - pCookie->dwMsgID1 = dwMsgID1; - pCookie->dwMsgID2 = dwMsgID2; - - OpenDirectConnection(hContact, DIRECTCONN_REVERSE, (void*)pCookie); - } - else debugLogA("Warning: Unsupported direct protocol version in %s", "Reverse Connect Request"); - } - } - else debugLogA("Malformed %s", "Reverse Connect Request"); - } - else debugLogA("Warning, no 0x2711 TLV in message (format 2)"); - - // Clean up - disposeChain(&chain); - } - else if (CompareGUIDs(q1, q2, q3, q4, MCAP_FILE_TRANSFER)) // this is an OFT packet - handleRecvServMsgOFT(pDataBuf, wTLVLen, dwUin, szUID, dwMsgID1, dwMsgID2, wCommand); - - else if (CompareGUIDs(q1, q2, q3, q4, MCAP_CONTACTS)) // this is Contacts Transfer - handleRecvServMsgContacts(pDataBuf, wTLVLen, dwUin, szUID, dwMsgID1, dwMsgID2, wCommand); - - else // here should be detection of extra data streams (Xtraz) - debugLogA("Unknown Message Format Capability"); - } - else debugLogA("Unsupported TLV (%u) in message (format %u)", wTLVType, 2); - - SAFE_FREE((void**)&pBuf); -} - - -void CIcqProto::parseServRelayData(BYTE *pDataBuf, size_t wLen, MCONTACT hContact, DWORD dwUin, char *szUID, DWORD dwMsgID1, DWORD dwMsgID2, WORD wAckType) -{ - WORD wId; - - if (wLen < 2) { - debugLogA("Message (format %u) - Ignoring empty message", 2); - return; - } - - unpackLEWord(&pDataBuf, &wId); // Incorrect identification, but working - wLen -= 2; - - // Only 0x1B are real messages - if (wId == 0x001B) { - WORD wVersion; - WORD wCookie; - DWORD dwGuid1, dwGuid2, dwGuid3, dwGuid4; - - if (wLen < 31) { // just check if we have data to work with - debugLogA("Message (format %u) - Ignoring empty message", 2); - return; - } - - unpackLEWord(&pDataBuf, &wVersion); - wLen -= 2; - - if (hContact != INVALID_CONTACT_ID) - setWord(hContact, "Version", wVersion); - - unpackDWord(&pDataBuf, &dwGuid1); // plugin type GUID - unpackDWord(&pDataBuf, &dwGuid2); - unpackDWord(&pDataBuf, &dwGuid3); - unpackDWord(&pDataBuf, &dwGuid4); - wLen -= 16; - - // Skip lots of unused stuff - pDataBuf += 9; - wLen -= 9; - - unpackLEWord(&pDataBuf, &wId); - wLen -= 2; - - unpackLEWord(&pDataBuf, &wCookie); - wLen -= 2; - - if (CompareGUIDs(dwGuid1, dwGuid2, dwGuid3, dwGuid4, PSIG_MESSAGE)) { // is this a normal message ? - BYTE bMsgType; - BYTE bFlags; - WORD wStatus, wPritority; - WORD wMsgLen; - - if (wLen < 20) { // check if there is everything that should be there - debugLogA("Message (format %u) - Ignoring empty message", 2); - return; - } - - pDataBuf += 12; /* all zeroes */ - wLen -= 12; - unpackByte(&pDataBuf, &bMsgType); - wLen -= 1; - unpackByte(&pDataBuf, &bFlags); - wLen -= 1; - - // Status - unpackLEWord(&pDataBuf, &wStatus); - wLen -= 2; - - // Priority - unpackLEWord(&pDataBuf, &wPritority); - wLen -= 2; - debugLogA("Priority: %u", wPritority); - - // Message - unpackLEWord(&pDataBuf, &wMsgLen); - wLen -= 2; - - // HANDLERS - switch (bMsgType) { // File messages, handled by the file module - case MTYPE_FILEREQ: - if (!dwUin) { // AIM cannot send this, just sanity - debugLogA("Error: Malformed UIN in packet"); - return; - } - { - char* szMsg = (char *)_alloca(wMsgLen + 1); - memcpy(szMsg, pDataBuf, wMsgLen); - szMsg[wMsgLen] = '\0'; - pDataBuf += wMsgLen; - wLen -= wMsgLen; - - if (wAckType == 0 || wAckType == 1) - // File requests 7 - handleFileRequest(pDataBuf, dwUin, wCookie, dwMsgID1, dwMsgID2, szMsg, 7, FALSE); - else if (wAckType == 2) - // File reply 7 - handleFileAck(pDataBuf, wLen, dwUin, wCookie, wStatus); - else - debugLogA("Ignored strange file message"); - } - break; - - // Chat messages, handled by the chat module - case MTYPE_CHAT: - // TODO: this type is deprecated - break; - - // Plugin messages, need further parsing - case MTYPE_PLUGIN: - if (wLen < wMsgLen) { // sanity check - debugLogA("Error: Malformed server Greeting message"); - return; - } - - parseServRelayPluginData(pDataBuf + wMsgLen, wLen - wMsgLen, dwUin, szUID, dwMsgID1, dwMsgID2, wAckType, bFlags, wStatus, wCookie, wVersion); - break; - - // Everything else - default: - if (!dwUin) { // AIM cannot send this, just sanity - debugLogA("Error: Malformed UIN in packet"); - return; - } - - message_ack_params pMsgAck = { 0 }; - pMsgAck.bType = MAT_SERVER_ADVANCED; - pMsgAck.dwUin = dwUin; - pMsgAck.dwMsgID1 = dwMsgID1; - pMsgAck.dwMsgID2 = dwMsgID2; - pMsgAck.wCookie = wCookie; - pMsgAck.msgType = bMsgType; - pMsgAck.bFlags = bFlags; - handleMessageTypes(dwUin, szUID, time(0), dwMsgID1, dwMsgID2, wCookie, wVersion, bMsgType, bFlags, wAckType, wLen, wMsgLen, (char*)pDataBuf, 0, &pMsgAck); - break; - } - } - else if (CompareGUIDs(dwGuid1, dwGuid2, dwGuid3, dwGuid4, PSIG_INFO_PLUGIN)) { // info manager plugin - obsolete - if (!dwUin) { // AIM cannot send this, just sanity - debugLogA("Error: Malformed UIN in packet"); - return; - } - - BYTE bMsgType; - BYTE bLevel; - - pDataBuf += 16; /* unused stuff */ - wLen -= 16; - unpackByte(&pDataBuf, &bMsgType); - wLen -= 1; - - pDataBuf += 3; // unknown - wLen -= 3; - unpackByte(&pDataBuf, &bLevel); - if (bLevel != 0 || wLen < 16) { - debugLogA("Invalid %s Manager Plugin message from %u", "Info", dwUin); - return; - } - unpackDWord(&pDataBuf, &dwGuid1); // plugin request GUID - unpackDWord(&pDataBuf, &dwGuid2); - unpackDWord(&pDataBuf, &dwGuid3); - unpackDWord(&pDataBuf, &dwGuid4); - wLen -= 16; - - if (CompareGUIDs(dwGuid1, dwGuid2, dwGuid3, dwGuid4, PMSG_QUERY_INFO)) - debugLogA("User %u requests our %s plugin list. NOT SUPPORTED", dwUin, "info"); - else - debugLogA("Unknown %s Manager message from %u", "Info", dwUin); - } - else if (CompareGUIDs(dwGuid1, dwGuid2, dwGuid3, dwGuid4, PSIG_STATUS_PLUGIN)) { // status manager plugin - obsolete - if (!dwUin) { // AIM cannot send this, just sanity - debugLogA("Error: Malformed UIN in packet"); - return; - } - - BYTE bMsgType; - BYTE bLevel; - - pDataBuf += 16; /* unused stuff */ - wLen -= 16; - unpackByte(&pDataBuf, &bMsgType); - wLen -= 1; - - pDataBuf += 3; // unknown - wLen -= 3; - unpackByte(&pDataBuf, &bLevel); - if (bLevel != 0 || wLen < 16) { - debugLogA("Invalid %s Manager Plugin message from %u", "Status", dwUin); - return; - } - unpackDWord(&pDataBuf, &dwGuid1); // plugin request GUID - unpackDWord(&pDataBuf, &dwGuid2); - unpackDWord(&pDataBuf, &dwGuid3); - unpackDWord(&pDataBuf, &dwGuid4); - wLen -= 16; - - if (CompareGUIDs(dwGuid1, dwGuid2, dwGuid3, dwGuid4, PMSG_QUERY_STATUS)) - debugLogA("User %u requests our %s plugin list. NOT SUPPORTED", dwUin, "status"); - else - debugLogA("Unknown %s Manager message from %u", "Status", dwUin); - } - else debugLogA("Unknown signature (%08x-%08x-%08x-%08x) in message (format 2)", dwGuid1, dwGuid2, dwGuid3, dwGuid4); - } - else debugLogA("Unknown wId1 (%u) in message (format 2)", wId); -} - -void CIcqProto::parseServRelayPluginData(BYTE *pDataBuf, size_t wLen, DWORD dwUin, char *szUID, DWORD dwMsgID1, DWORD dwMsgID2, WORD wAckType, BYTE bFlags, WORD wStatus, WORD wCookie, WORD wVersion) -{ - int nTypeId; - WORD wFunction; - - debugLogA("Parsing Greeting message through server"); - - // Message plugin identification - if (!unpackPluginTypeId(&pDataBuf, &wLen, &nTypeId, &wFunction, FALSE)) return; - - if (wLen > 8) { - size_t dwLengthToEnd, dwDataLen; - - // Length of remaining data - unpackLEDWord(&pDataBuf, &dwLengthToEnd); - - // Length of message - unpackLEDWord(&pDataBuf, &dwDataLen); - wLen -= 8; - - if (dwDataLen > wLen) - dwDataLen = wLen; - - if (nTypeId == MTYPE_FILEREQ && wAckType == 2) { - if (!dwUin) { // AIM cannot send this, just sanity - debugLogA("Error: Malformed UIN in packet"); - return; - } - debugLogA("This is file ack"); - - char *szMsg = (char *)_alloca(dwDataLen + 1); - memcpy(szMsg, pDataBuf, dwDataLen); - szMsg[dwDataLen] = '\0'; - pDataBuf += dwDataLen; - wLen -= dwDataLen; - - handleFileAck(pDataBuf, wLen, dwUin, wCookie, wStatus); - } - else if (nTypeId == MTYPE_FILEREQ && wAckType == 1) { - if (!dwUin) { // AIM cannot send this, just sanity - debugLogA("Error: Malformed UIN in packet"); - return; - } - debugLogA("This is a file request"); - - char *szMsg = (char *)_alloca(dwDataLen + 1); - memcpy(szMsg, pDataBuf, dwDataLen); - szMsg[dwDataLen] = '\0'; - pDataBuf += dwDataLen; - wLen -= dwDataLen; - - handleFileRequest(pDataBuf, dwUin, wCookie, dwMsgID1, dwMsgID2, szMsg, 8, FALSE); - } - else if (nTypeId == MTYPE_CHAT && wAckType == 1) { // TODO: this is deprecated - if (!dwUin) { // AIM cannot send this, just sanity - debugLogA("Error: Malformed UIN in packet"); - return; - } - debugLogA("This is a chat request"); - - char *szMsg = (char *)_alloca(dwDataLen + 1); - memcpy(szMsg, pDataBuf, dwDataLen); - szMsg[dwDataLen] = '\0'; - pDataBuf += dwDataLen; - wLen -= dwDataLen; - - // handleChatRequest(pDataBuf, wLen, dwUin, wCookie, dwMsgID1, dwMsgID2, szMsg, 8); - } - else if (nTypeId == MTYPE_STATUSMSGEXT && wFunction >= 1 && wFunction <= 3) { // handle extended status message request - int nMsgType = 0; - - switch (wFunction) { - case 1: // Away - if (m_iStatus == ID_STATUS_ONLINE || m_iStatus == ID_STATUS_INVISIBLE) - nMsgType = MTYPE_AUTOONLINE; - else if (m_iStatus == ID_STATUS_AWAY) - nMsgType = MTYPE_AUTOAWAY; - else if (m_iStatus == ID_STATUS_FREECHAT) - nMsgType = MTYPE_AUTOFFC; - break; - - case 2: // Busy - if (m_iStatus == ID_STATUS_OCCUPIED) - nMsgType = MTYPE_AUTOBUSY; - else if (m_iStatus == ID_STATUS_DND) - nMsgType = MTYPE_AUTODND; - break; - - case 3: // N/A - if (m_iStatus == ID_STATUS_NA) - nMsgType = MTYPE_AUTONA; - } - handleMessageTypes(dwUin, szUID, time(0), dwMsgID1, dwMsgID2, wCookie, wVersion, nMsgType, bFlags, wAckType, dwLengthToEnd, 0, (char*)pDataBuf, MTF_PLUGIN | MTF_STATUS_EXTENDED, nullptr); - } - else if (nTypeId) { - if (!dwUin) { // AIM cannot send this, just sanity - debugLogA("Error: Malformed UIN in packet"); - return; - } - message_ack_params pMsgAck = { 0 }; - - pMsgAck.bType = MAT_SERVER_ADVANCED; - pMsgAck.dwUin = dwUin; - pMsgAck.dwMsgID1 = dwMsgID1; - pMsgAck.dwMsgID2 = dwMsgID2; - pMsgAck.wCookie = wCookie; - pMsgAck.msgType = nTypeId; - pMsgAck.bFlags = bFlags; - handleMessageTypes(dwUin, szUID, time(0), dwMsgID1, dwMsgID2, wCookie, wVersion, nTypeId, bFlags, wAckType, dwLengthToEnd, dwDataLen, (char*)pDataBuf, MTF_PLUGIN, &pMsgAck); - } - else debugLogA("Unsupported plugin message type %d", nTypeId); - } - else debugLogA("Error: Malformed server plugin message"); -} - -void CIcqProto::handleRecvServMsgContacts(BYTE *buf, size_t wLen, DWORD dwUin, char *szUID, DWORD dwID1, DWORD dwID2, WORD wCommand) -{ - MCONTACT hContact = HContactFromUID(dwUin, szUID, nullptr); - - if (wCommand == 0) { // received contacts - if (wLen < 4) { // just check if at least one tlv is there - debugLogA("Message (format %u) - Ignoring empty contacts message", 2); - return; - } - oscar_tlv_chain *chain = readIntoTLVChain(&buf, wLen, 0); - if (!chain) { // sanity check - debugLogA("Message (format %u) - Invalid data", 2); - return; - } - - WORD wAckType = chain->getWord(0x0A, 1); - - if (wAckType == 1) { // it is really message containing contacts, parse them - oscar_tlv *tlvUins = chain->getTLV(0x2711, 1); - oscar_tlv *tlvNames = chain->getTLV(0x2712, 1); - - if (!tlvUins || tlvUins->wLen < 4) { - debugLogA("Malformed '%s' message", "contacts"); - disposeChain(&chain); - return; - } - int nContacts = 0x10, iContact = 0; - ICQSEARCHRESULT **contacts = (ICQSEARCHRESULT**)SAFE_MALLOC(nContacts * sizeof(ICQSEARCHRESULT*)); - WORD wContactsGroup = 0; - int valid = 1; - BYTE *pBuffer = tlvUins->pData; - int nLen = tlvUins->wLen; - - while (nLen > 2) { // parse UIDs - if (!wContactsGroup) { - WORD wGroupLen; - - unpackWord(&pBuffer, &wGroupLen); - nLen -= 2; - if (nLen >= wGroupLen + 2) { - pBuffer += wGroupLen; - unpackWord(&pBuffer, &wContactsGroup); - nLen -= wGroupLen + 2; - } - else - break; - } - else { // group parsed, UIDs waiting - WORD wUidLen; - - unpackWord(&pBuffer, &wUidLen); - nLen -= 2; - if (nLen >= wUidLen) { - char *szUid = (char*)SAFE_MALLOC(wUidLen + 1); - unpackString(&pBuffer, szUid, wUidLen); - nLen -= wUidLen; - - if (iContact >= nContacts) { // the list is too small, resize it - nContacts += 0x10; - contacts = (ICQSEARCHRESULT**)SAFE_REALLOC(contacts, nContacts * sizeof(ICQSEARCHRESULT*)); - } - contacts[iContact] = (ICQSEARCHRESULT*)SAFE_MALLOC(sizeof(ICQSEARCHRESULT)); - contacts[iContact]->hdr.cbSize = sizeof(ICQSEARCHRESULT); - contacts[iContact]->hdr.flags = PSR_UNICODE; - contacts[iContact]->hdr.nick.w = null_strdup(L""); - contacts[iContact]->hdr.id.w = ansi_to_unicode(szUid); - - if (IsStringUIN(szUid)) { // icq contact - contacts[iContact]->uin = atoi(szUid); - if (contacts[iContact]->uin == 0) - valid = 0; - } - else { // aim contact - if (!mir_strlen(szUid)) - valid = 0; - } - iContact++; - - SAFE_FREE(&szUid); - } - else { - if (wContactsGroup) valid = 0; - break; - } - - wContactsGroup--; - } - } - if (!iContact || !valid) { - debugLogA("Malformed '%s' message", "contacts"); - disposeChain(&chain); - for (int i = 0; i < iContact; i++) { - SAFE_FREE(&contacts[i]->hdr.id.w); - SAFE_FREE(&contacts[i]->hdr.nick.w); - SAFE_FREE((void**)&contacts[i]); - } - SAFE_FREE((void**)&contacts); - return; - } - nContacts = iContact; - if (tlvNames && tlvNames->wLen >= 4) { // parse names, if available - pBuffer = tlvNames->pData; - nLen = tlvNames->wLen; - iContact = 0; - - while (nLen > 2) { // parse Names - if (!wContactsGroup) { - WORD wGroupLen; - - unpackWord(&pBuffer, &wGroupLen); - nLen -= 2; - if (nLen >= wGroupLen + 2) { - pBuffer += wGroupLen; - unpackWord(&pBuffer, &wContactsGroup); - nLen -= wGroupLen + 2; - } - else - break; - } - else { // group parsed, Names waiting - WORD wNickLen; - - unpackWord(&pBuffer, &wNickLen); - nLen -= 2; - if (nLen >= wNickLen) { - WORD wNickTLV; - size_t wNickTLVLen; - char *pNick = nullptr; - - unpackTypedTLV(pBuffer, wNickLen, 0x01, &wNickTLV, &wNickTLVLen, (LPBYTE*)&pNick); - if (wNickTLV == 0x01) { - SAFE_FREE(&contacts[iContact]->hdr.nick.w); - contacts[iContact]->hdr.nick.w = make_unicode_string(pNick); - } - else - SAFE_FREE(&pNick); - pBuffer += wNickLen; - nLen -= wNickLen; - - iContact++; - if (iContact >= nContacts) break; - } - else - break; - - wContactsGroup--; - } - } - } - - if (!valid) - debugLogA("Malformed '%s' message", "contacts"); - else { - int bAdded; - hContact = HContactFromUID(dwUin, szUID, &bAdded); - - // ack the message - icq_sendContactsAck(dwUin, szUID, dwID1, dwID2); - - PROTORECVEVENT pre = { 0 }; - pre.timestamp = (DWORD)time(0); - pre.szMessage = (char *)contacts; - pre.lParam = nContacts; - ProtoChainRecv(hContact, PSR_CONTACTS, 0, (LPARAM)&pre); - } - - for (int i = 0; i < iContact; i++) { - SAFE_FREE(&contacts[i]->hdr.id.w); - SAFE_FREE(&contacts[i]->hdr.nick.w); - SAFE_FREE((void**)&contacts[i]); - } - SAFE_FREE((void**)&contacts); - } - else - debugLogA("Error: Received unknown contacts message, ignoring."); - // Clean up - disposeChain(&chain); - } - else if (wCommand == 1) { - debugLogA("Cannot handle abort messages yet... :("); - } - else if (wCommand == 2) { // acknowledgement - DWORD dwCookie; - MCONTACT hCookieContact; - if (FindMessageCookie(dwID1, dwID2, &dwCookie, &hCookieContact, nullptr)) { - if (hCookieContact != hContact) - debugLogA("Warning: Ack Contact does not match Cookie Contact(0x%x != 0x%x)", hContact, hCookieContact); - - ProtoBroadcastAck(hContact, ACKTYPE_CONTACTS, ACKRESULT_SUCCESS, (HANDLE)dwCookie, 0); - - ReleaseCookie(dwCookie); - } - else debugLogA("Warning: Unexpected Contact Transfer ack from %s", strUID(dwUin, szUID)); - } -} - -void CIcqProto::handleRecvServMsgType4(BYTE *buf, size_t wLen, DWORD dwUin, char *szUID, DWORD dwMsgID1, DWORD dwMsgID2, DWORD dwRef) -{ - WORD wTLVType; - size_t wTLVLen; - BYTE* pDataBuf; - DWORD dwUin2; - - if (wLen < 2) { - debugLogA("Message (format %u) - Ignoring empty message", 4); - return; - } - - // Unpack the first TLV(5) - unpackTypedTLV(buf, wLen, 5, &wTLVType, &wTLVLen, &pDataBuf); - debugLogA("Message (format %u) - UID: %s", 4, strUID(dwUin, szUID)); - - // It must be TLV(5) - if (wTLVType == 5) { - BYTE bMsgType; - BYTE bFlags; - BYTE* pmsg = pDataBuf; - size_t wMsgLen; - - unpackLEDWord(&pmsg, &dwUin2); - - if (dwUin2 == dwUin) { - unpackByte(&pmsg, &bMsgType); - unpackByte(&pmsg, &bFlags); - unpackLEWord(&pmsg, &wMsgLen); - - if (bMsgType == 0 && wMsgLen == 1) - debugLogA("User %u probably checks his ignore state.", dwUin); - else { - cookie_offline_messages *cookie; - DWORD dwRecvTime = (DWORD)time(0); - - if (!(dwRef & 0x80000000) && FindCookie(dwRef, nullptr, (void**)&cookie)) { - WORD wTimeTLVType; - size_t wTimeTLVLen; - BYTE *pTimeTLV = nullptr; - - cookie->nMessages++; - - unpackTypedTLV(buf, wLen, 0x16, &wTimeTLVType, &wTimeTLVLen, &pTimeTLV); - if (pTimeTLV && wTimeTLVType == 0x16 && wTimeTLVLen == 4) { // found Offline timestamp - BYTE *pBuf = pTimeTLV; - unpackDWord(&pBuf, &dwRecvTime); - debugLogA("Message (format %u) - Offline timestamp is %s", 4, time2text(dwRecvTime)); - } - SAFE_FREE((void**)&pTimeTLV); - } - - if (bMsgType == MTYPE_PLUGIN) { - wLen = wTLVLen - 8; - - debugLogA("Parsing Greeting message through server"); - - pmsg += wMsgLen; - wLen -= wMsgLen; - - int typeId; - if (unpackPluginTypeId(&pmsg, &wLen, &typeId, nullptr, FALSE) && wLen > 8) { - size_t dwLengthToEnd, dwDataLen; - - // Length of remaining data - unpackLEDWord(&pmsg, &dwLengthToEnd); - - // Length of message - unpackLEDWord(&pmsg, &dwDataLen); - wLen -= 8; - - if (dwDataLen > wLen) - dwDataLen = wLen; - - if (typeId) { - uid_str szUid; - handleMessageTypes(dwUin, szUid, dwRecvTime, dwMsgID1, dwMsgID2, 0, 0, typeId, bFlags, 0, dwLengthToEnd, dwDataLen, (char*)pmsg, MTF_PLUGIN, nullptr); - } - else debugLogA("Unsupported plugin message type %d", typeId); - } - } - else { - uid_str szUid; - handleMessageTypes(dwUin, szUid, dwRecvTime, dwMsgID1, dwMsgID2, 0, 0, bMsgType, bFlags, 0, wTLVLen - 8, wMsgLen, (char*)pmsg, 0, nullptr); - } - } - } - else debugLogA("Ignoring spoofed TYPE4 message thru server from %d", dwUin); - } - else debugLogA("Unsupported TLV (%u) in message (format %u)", wTLVType, 4); - - SAFE_FREE((void**)&pDataBuf); -} - - -// -// Helper functions -// - -static int TypeGUIDToTypeId(DWORD dwGuid1, DWORD dwGuid2, DWORD dwGuid3, DWORD dwGuid4, WORD wType) -{ - int nTypeID = MTYPE_UNKNOWN; - - if (CompareGUIDs(dwGuid1, dwGuid2, dwGuid3, dwGuid4, MGTYPE_STATUSMSGEXT)) { - nTypeID = MTYPE_STATUSMSGEXT; - } - else if (wType == MGTYPE_UNDEFINED) { - if (CompareGUIDs(dwGuid1, dwGuid2, dwGuid3, dwGuid4, PSIG_MESSAGE)) { // icq6 message ack - nTypeID = MTYPE_PLAIN; - } - } - else if (wType == MGTYPE_STANDARD_SEND) { - if (CompareGUIDs(dwGuid1, dwGuid2, dwGuid3, dwGuid4, MGTYPE_WEBURL)) { - nTypeID = MTYPE_URL; - } - else if (CompareGUIDs(dwGuid1, dwGuid2, dwGuid3, dwGuid4, MGTYPE_CONTACTS)) { - nTypeID = MTYPE_CONTACTS; - } - else if (CompareGUIDs(dwGuid1, dwGuid2, dwGuid3, dwGuid4, MGTYPE_CHAT)) { - nTypeID = MTYPE_CHAT; - } - else if (CompareGUIDs(dwGuid1, dwGuid2, dwGuid3, dwGuid4, MGTYPE_FILE)) { - nTypeID = MTYPE_FILEREQ; - } - else if (CompareGUIDs(dwGuid1, dwGuid2, dwGuid3, dwGuid4, MGTYPE_GREETING_CARD)) { - nTypeID = MTYPE_GREETINGCARD; - } - else if (CompareGUIDs(dwGuid1, dwGuid2, dwGuid3, dwGuid4, MGTYPE_MESSAGE)) { - nTypeID = MTYPE_MESSAGE; - } - else if (CompareGUIDs(dwGuid1, dwGuid2, dwGuid3, dwGuid4, MGTYPE_SMS_MESSAGE)) { - nTypeID = MTYPE_SMS_MESSAGE; - } - } - else if (wType == MGTYPE_CONTACTS_REQUEST) { - if (CompareGUIDs(dwGuid1, dwGuid2, dwGuid3, dwGuid4, MGTYPE_CONTACTS)) { - nTypeID = MTYPE_REQUESTCONTACTS; - } - else if (CompareGUIDs(dwGuid1, dwGuid2, dwGuid3, dwGuid4, MGTYPE_XTRAZ_SCRIPT)) { - nTypeID = MTYPE_SCRIPT_DATA; - } - } - else if (CompareGUIDs(dwGuid1, dwGuid2, dwGuid3, dwGuid4, MGTYPE_XTRAZ_SCRIPT)) { - if (wType == MGTYPE_SCRIPT_INVITATION) { - nTypeID = MTYPE_SCRIPT_INVITATION; - } - else if (wType == MGTYPE_SCRIPT_NOTIFY) { - nTypeID = MTYPE_SCRIPT_NOTIFY; - } - } - - return nTypeID; -} - - -int CIcqProto::unpackPluginTypeId(BYTE **pBuffer, size_t *pwLen, int *pTypeId, WORD *pFunctionId, BOOL bThruDC) -{ - size_t wLen = *pwLen, wInfoLen, dwPluginNameLen; - DWORD q1, q2, q3, q4; - WORD qt; - - if (wLen < 24) - return 0; // Failure - - unpackLEWord(pBuffer, &wInfoLen); - - unpackDWord(pBuffer, &q1); // get data GUID & function id - unpackDWord(pBuffer, &q2); - unpackDWord(pBuffer, &q3); - unpackDWord(pBuffer, &q4); - unpackLEWord(pBuffer, &qt); - wLen -= 20; - - if (pFunctionId) *pFunctionId = qt; - - unpackLEDWord(pBuffer, &dwPluginNameLen); - wLen -= 4; - - if (dwPluginNameLen > wLen) { // check for malformed plugin name - dwPluginNameLen = wLen; - NetLog_Uni(bThruDC, "Warning: malformed size of plugin name."); - } - char *szPluginName = (char *)_alloca(dwPluginNameLen + 1); - memcpy(szPluginName, *pBuffer, dwPluginNameLen); - szPluginName[dwPluginNameLen] = '\0'; - wLen -= dwPluginNameLen; - - *pBuffer += dwPluginNameLen; - - int typeId = TypeGUIDToTypeId(q1, q2, q3, q4, qt); - if (!typeId) - NetLog_Uni(bThruDC, "Error: Unknown type {%08x-%08x-%08x-%08x:%04x}: %s", q1, q2, q3, q4, qt, szPluginName); - - if (wInfoLen >= 22 + dwPluginNameLen) { // sanity checking - wInfoLen -= 22 + dwPluginNameLen; - - // check if enough data is available - skip remaining bytes of info block - if (wLen >= wInfoLen) { - *pBuffer += wInfoLen; - wLen -= wInfoLen; - } - } - - *pwLen = wLen; - *pTypeId = typeId; - - return 1; // Success -} - - -int getPluginTypeIdLen(int nTypeID) -{ - switch (nTypeID) { - case MTYPE_SCRIPT_NOTIFY: - return 0x51; - - case MTYPE_FILEREQ: - return 0x2B; - - case MTYPE_AUTOONLINE: - case MTYPE_AUTOAWAY: - case MTYPE_AUTOBUSY: - case MTYPE_AUTODND: - case MTYPE_AUTOFFC: - return 0x3C; - - case MTYPE_AUTONA: - return 0x3B; - - default: - return 0; - } -} - - -void packPluginTypeId(icq_packet *packet, int nTypeID) -{ - switch (nTypeID) { - case MTYPE_SCRIPT_NOTIFY: - packLEWord(packet, 0x04f); // Length - - packGUID(packet, MGTYPE_XTRAZ_SCRIPT); // Message Type GUID - packLEWord(packet, MGTYPE_SCRIPT_NOTIFY); // Function ID - packLEDWord(packet, 0x002a); // Request type string - packBuffer(packet, (LPBYTE)"Script Plug-in: Remote Notification Arrive", 0x002a); - - packDWord(packet, 0x00000100); // Unknown binary stuff - packDWord(packet, 0x00000000); - packDWord(packet, 0x00000000); - packWord(packet, 0x0000); - packByte(packet, 0x00); - - break; - - case MTYPE_FILEREQ: - packLEWord(packet, 0x029); // Length - - packGUID(packet, MGTYPE_FILE); // Message Type GUID - packWord(packet, 0x0000); // Unknown - packLEDWord(packet, 0x0004); // Request type string - packBuffer(packet, (LPBYTE)"File", 0x0004); - - packDWord(packet, 0x00000100); // More unknown binary stuff - packDWord(packet, 0x00010000); - packDWord(packet, 0x00000000); - packWord(packet, 0x0000); - packByte(packet, 0x00); - - break; - - case MTYPE_AUTOONLINE: - case MTYPE_AUTOAWAY: - case MTYPE_AUTOFFC: - packLEWord(packet, 0x03A); // Length - - packGUID(packet, MGTYPE_STATUSMSGEXT); // Message Type GUID - - packLEWord(packet, 1); // Function ID - packLEDWord(packet, 0x13); // Request type string - packBuffer(packet, (LPBYTE)"Away Status Message", 0x13); - - packDWord(packet, 0x01000000); // Unknown binary stuff - packDWord(packet, 0x00000000); - packDWord(packet, 0x00000000); - packDWord(packet, 0x00000000); - packByte(packet, 0x00); - - break; - - case MTYPE_AUTOBUSY: - case MTYPE_AUTODND: - packLEWord(packet, 0x03A); // Length - - packGUID(packet, MGTYPE_STATUSMSGEXT); // Message Type GUID - - packLEWord(packet, 2); // Function ID - packLEDWord(packet, 0x13); // Request type string - packBuffer(packet, (LPBYTE)"Busy Status Message", 0x13); - - packDWord(packet, 0x02000000); // Unknown binary stuff - packDWord(packet, 0x00000000); - packDWord(packet, 0x00000000); - packDWord(packet, 0x00000000); - packByte(packet, 0x00); - - break; - - case MTYPE_AUTONA: - packLEWord(packet, 0x039); // Length - - packGUID(packet, MGTYPE_STATUSMSGEXT); // Message Type GUID - - packLEWord(packet, 3); // Function ID - packLEDWord(packet, 0x12); // Request type string - packBuffer(packet, (LPBYTE)"N/A Status Message", 0x12); - - packDWord(packet, 0x03000000); // Unknown binary stuff - packDWord(packet, 0x00000000); - packDWord(packet, 0x00000000); - packDWord(packet, 0x00000000); - packByte(packet, 0x00); - - break; - } -} - - -void CIcqProto::handleStatusMsgReply(const char *szPrefix, MCONTACT hContact, DWORD dwUin, int bMsgType, WORD wCookie, const char *szMsg) -{ - if (hContact == INVALID_CONTACT_ID) { - debugLogA("%sIgnoring status message from unknown contact %u", szPrefix, dwUin); - return; - } - - int status = AwayMsgTypeToStatus(bMsgType); - if (status == ID_STATUS_OFFLINE) { - debugLogA("%sIgnoring unknown status message from %u", szPrefix, dwUin); - return; - } - - // it is probably UTF-8 status reply - PROTORECVEVENT pre = { 0 }; - pre.szMessage = (char*)szMsg; - pre.timestamp = time(0); - pre.lParam = wCookie; - ProtoChainRecv(hContact, PSR_AWAYMSG, status, (LPARAM)&pre); -} - - -HANDLE CIcqProto::handleMessageAck(DWORD dwUin, char *szUID, WORD wCookie, int type, PBYTE buf, BYTE bFlags) -{ - if (bFlags == 3) { - MCONTACT hCookieContact; - cookie_message_data *pCookieData = nullptr; - - MCONTACT hContact = HContactFromUID(dwUin, szUID, nullptr); - - if (!FindCookie(wCookie, &hCookieContact, (void**)&pCookieData)) { - debugLogA("%sIgnoring unrequested status message from %u", "handleMessageAck: ", dwUin); - - ReleaseCookie(wCookie); - return INVALID_HANDLE_VALUE; - } - - if (hContact != hCookieContact) { - debugLogA("%sAck Contact does not match Cookie Contact(0x%x != 0x%x)", "handleMessageAck: ", hContact, hCookieContact); - - ReleaseCookie(wCookie); - return INVALID_HANDLE_VALUE; - } - ReleaseCookie(wCookie); - - handleStatusMsgReply("handleMessageAck: ", hContact, dwUin, type, wCookie, (char*)buf); - } - else // Should not happen - debugLogA("%sIgnored type %u ack message (this should not happen)", "handleMessageAck: ", type); - - return INVALID_HANDLE_VALUE; -} - - -/* this function send all acks from handleMessageTypes */ -void CIcqProto::sendMessageTypesAck(MCONTACT hContact, int bUnicode, message_ack_params *pArgs) -{ - if (pArgs) { - if ((pArgs->msgType == MTYPE_PLAIN && !CallService(MS_IGNORE_ISIGNORED, hContact, IGNOREEVENT_MESSAGE)) - || (pArgs->msgType == MTYPE_URL && !CallService(MS_IGNORE_ISIGNORED, hContact, IGNOREEVENT_URL)) - || pArgs->msgType == MTYPE_CONTACTS) { - if (pArgs->bType == MAT_SERVER_ADVANCED) { // Only ack message packets - icq_sendAdvancedMsgAck(pArgs->dwUin, pArgs->dwMsgID1, pArgs->dwMsgID2, pArgs->wCookie, (BYTE)pArgs->msgType, pArgs->bFlags); - } - else if (pArgs->bType == MAT_DIRECT) { // Send acknowledgement - icq_sendDirectMsgAck(pArgs->pDC, pArgs->wCookie, (BYTE)pArgs->msgType, pArgs->bFlags, bUnicode ? (char *)CAP_UTF8MSGS : nullptr); - } - } - } -} - - -/* this function also processes direct packets, so it should be bulletproof */ -/* pMsg points to the beginning of the message */ -void CIcqProto::handleMessageTypes(DWORD dwUin, char *szUID, DWORD dwTimestamp, DWORD dwMsgID, DWORD dwMsgID2, WORD wCookie, WORD wVersion, int type, int flags, WORD wAckType, size_t dwDataLen, size_t wMsgLen, char *pMsg, int nMsgFlags, message_ack_params *pAckParams) -{ - MCONTACT hContact = INVALID_CONTACT_ID; - BOOL bThruDC = (nMsgFlags & MTF_DIRECT) == MTF_DIRECT; - int bAdded; - - if (dwDataLen < wMsgLen) { - NetLog_Uni(bThruDC, "Ignoring overflowed message"); - return; - } - - if (wAckType == 2) { - handleMessageAck(dwUin, szUID, wCookie, type, (LPBYTE)pMsg, (BYTE)flags); - return; - } - - char *szMsg = (char *)SAFE_MALLOC(wMsgLen + 1); - if (wMsgLen > 0) { - memcpy(szMsg, pMsg, wMsgLen); - pMsg += wMsgLen; - dwDataLen -= wMsgLen; - } - szMsg[wMsgLen] = '\0'; - - - char *pszMsgField[2 * MAX_CONTACTSSEND + 1]; - int nMsgFields = 0; - - pszMsgField[0] = szMsg; - if (type == MTYPE_URL || type == MTYPE_AUTHREQ || type == MTYPE_ADDED || type == MTYPE_CONTACTS || type == MTYPE_EEXPRESS || type == MTYPE_WWP) { - nMsgFields = 1; - for (char *pszMsg = szMsg; *pszMsg; pszMsg++) { - if ((BYTE)*pszMsg == 0xFE) { - *pszMsg = '\0'; - pszMsgField[nMsgFields++] = pszMsg + 1; - if (nMsgFields >= _countof(pszMsgField)) - break; - } - } - } - - switch (type) { - case MTYPE_PLAIN: /* plain message */ - { - PROTORECVEVENT pre = { 0 }; - bool bUtf8 = false; - - // Check if this message is marked as UTF8 encoded - if (dwDataLen > 12) { - DWORD dwGuidLen = 0; - int bDoubleMsg = 0; - - if (bThruDC) { - DWORD dwExtraLen = *(DWORD*)pMsg; - - if (dwExtraLen < dwDataLen && !strncmp(szMsg, "{\\rtf", 5)) { // it is icq5 sending us crap, get real message from it - WCHAR* usMsg = (WCHAR*)_alloca((dwExtraLen + 1) * sizeof(WCHAR)); - // make sure it is null-terminated - wcsncpy(usMsg, (WCHAR*)(pMsg + 4), dwExtraLen); - usMsg[dwExtraLen] = '\0'; - SAFE_FREE(&szMsg); - szMsg = (char*)make_utf8_string(usMsg); - - if (!IsUnicodeAscii(usMsg, dwExtraLen)) - bUtf8 = true; // only mark real non-ascii messages as unicode - - bDoubleMsg = 1; - } - } - - if (!bDoubleMsg) { - dwGuidLen = *(DWORD*)(pMsg + 8); - dwDataLen -= 12; - pMsg += 12; - } - - while ((dwGuidLen >= 38) && (dwDataLen >= dwGuidLen)) { - if (!strncmp(pMsg, CAP_UTF8MSGS, 38)) { // Found UTF8 cap, convert message to ansi - bUtf8 = true; - break; - } - else if (!strncmp(pMsg, CAP_RTFMSGS, 38)) { // Found RichText cap - NetLog_Uni(bThruDC, "Warning: User %u sends us RichText.", dwUin); - break; - } - - dwGuidLen -= 38; - dwDataLen -= 38; - pMsg += 38; - } - } - - hContact = HContactFromUIN(dwUin, &bAdded); - sendMessageTypesAck(hContact, bUtf8, pAckParams); - - if (!bUtf8 && !IsUSASCII(szMsg, mir_strlen(szMsg))) { // message is Ansi and contains national characters, create Unicode part by codepage - char *usMsg = convertMsgToUserSpecificUtf(hContact, szMsg); - if (usMsg) { - SAFE_FREE(&szMsg); - szMsg = (char*)usMsg; - } - } - - pre.timestamp = dwTimestamp; - pre.szMessage = (char *)szMsg; - ProtoChainRecvMsg(hContact, &pre); - } - break; - - case MTYPE_URL: - if (nMsgFields < 2) { - NetLog_Uni(bThruDC, "Malformed '%s' message", "URL"); - break; - } - - hContact = HContactFromUIN(dwUin, &bAdded); - sendMessageTypesAck(hContact, 0, pAckParams); - { - char *szTitle = ICQTranslateUtf(LPGEN("Incoming URL:")); - char *szDataDescr = ansi_to_utf8(pszMsgField[0]); - char *szDataUrl = ansi_to_utf8(pszMsgField[1]); - char *szBlob = (char *)SAFE_MALLOC(mir_strlen(szTitle) + mir_strlen(szDataDescr) + mir_strlen(szDataUrl) + 8); - mir_strcpy(szBlob, szTitle); - mir_strcat(szBlob, " "); - mir_strcat(szBlob, szDataDescr); // Description - mir_strcat(szBlob, "\r\n"); - mir_strcat(szBlob, szDataUrl); // URL - SAFE_FREE(&szTitle); - SAFE_FREE(&szDataDescr); - SAFE_FREE(&szDataUrl); - - PROTORECVEVENT pre = { 0 }; - pre.timestamp = dwTimestamp; - pre.szMessage = (char *)szBlob; - ProtoChainRecvMsg(hContact, &pre); - SAFE_FREE(&szBlob); - } - break; - - case MTYPE_AUTHREQ: /* auth request */ - /* format: nick FE first FE last FE email FE unk-char FE msg 00 */ - if (nMsgFields < 6) { - debugLogA("Malformed '%s' message", "auth req"); - break; - } - { - DB_AUTH_BLOB blob(hContact, pszMsgField[0], pszMsgField[1], pszMsgField[2], pszMsgField[3], pszMsgField[5]); - blob.set_uin(dwUin); - - PROTORECVEVENT pre = { 0 }; - pre.timestamp = dwTimestamp; - pre.lParam = blob.size(); - pre.szMessage = blob; - ProtoChainRecv(hContact, PSR_AUTH, 0, (LPARAM)&pre); - } - break; - - case MTYPE_ADDED: /* 'you were added' */ - /* format: nick FE first FE last FE email 00 */ - if (nMsgFields < 4) { - debugLogA("Malformed '%s' message", "you were added"); - break; - } - hContact = HContactFromUIN(dwUin, &bAdded); - { - // blob is: uin(DWORD), hcontact(HANDLE), nick(ASCIIZ), first(ASCIIZ), last(ASCIIZ), email(ASCIIZ) - size_t cbBlob = sizeof(DWORD) * 2 + mir_strlen(pszMsgField[0]) + mir_strlen(pszMsgField[1]) + mir_strlen(pszMsgField[2]) + mir_strlen(pszMsgField[3]) + 4; - PBYTE pBlob, pCurBlob = pBlob = (PBYTE)_alloca(cbBlob); - *(DWORD*)pCurBlob = dwUin; pCurBlob += sizeof(DWORD); - *(DWORD*)pCurBlob = DWORD(hContact); pCurBlob += sizeof(DWORD); - mir_strcpy((char*)pCurBlob, pszMsgField[0]); pCurBlob += mir_strlen((char*)pCurBlob) + 1; - mir_strcpy((char*)pCurBlob, pszMsgField[1]); pCurBlob += mir_strlen((char*)pCurBlob) + 1; - mir_strcpy((char*)pCurBlob, pszMsgField[2]); pCurBlob += mir_strlen((char*)pCurBlob) + 1; - mir_strcpy((char*)pCurBlob, pszMsgField[3]); - AddEvent(NULL, EVENTTYPE_ADDED, dwTimestamp, 0, cbBlob, pBlob); - } - break; - - case MTYPE_CONTACTS: - { - char* pszNContactsEnd; - int nContacts; - if (nMsgFields < 3 || - (nContacts = strtol(pszMsgField[0], &pszNContactsEnd, 10)) == 0 || - pszNContactsEnd - pszMsgField[0] != (int)mir_strlen(pszMsgField[0]) || - nMsgFields < nContacts * 2 + 1) { - NetLog_Uni(bThruDC, "Malformed '%s' message", "contacts"); - } - else { - int valid = 1; - ICQSEARCHRESULT** isrList = (ICQSEARCHRESULT**)_alloca(nContacts * sizeof(ICQSEARCHRESULT*)); - for (int i = 0; i < nContacts; i++) { - isrList[i] = (ICQSEARCHRESULT*)SAFE_MALLOC(sizeof(ICQSEARCHRESULT)); - isrList[i]->hdr.cbSize = sizeof(ICQSEARCHRESULT); - isrList[i]->hdr.flags = PSR_UNICODE; - if (IsStringUIN(pszMsgField[1 + i * 2])) { // icq contact - isrList[i]->uin = atoi(pszMsgField[1 + i * 2]); - if (isrList[i]->uin == 0) - valid = 0; - } - else { // aim contact - if (!mir_strlen(pszMsgField[1 + i * 2])) - valid = 0; - } - isrList[i]->hdr.id.w = ansi_to_unicode(pszMsgField[1 + i * 2]); - isrList[i]->hdr.nick.w = ansi_to_unicode(pszMsgField[2 + i * 2]); - } - - if (!valid) - NetLog_Uni(bThruDC, "Malformed '%s' message", "contacts"); - else { - hContact = HContactFromUIN(dwUin, &bAdded); - sendMessageTypesAck(hContact, 0, pAckParams); - - PROTORECVEVENT pre = { 0 }; - pre.timestamp = dwTimestamp; - pre.szMessage = (char *)isrList; - pre.lParam = nContacts; - ProtoChainRecv(hContact, PSR_CONTACTS, 0, (LPARAM)&pre); - } - - for (int i = 0; i < nContacts; i++) { - SAFE_FREE(&isrList[i]->hdr.id.w); - SAFE_FREE(&isrList[i]->hdr.nick.w); - SAFE_FREE((void**)&isrList[i]); - } - } - } - break; - - case MTYPE_PLUGIN: // FIXME: this should be removed - it is never called - hContact = NULL; - - switch (dwUin) { - case 1111: /* icqmail 'you've got mail' - not processed */ - break; - } - break; - - case MTYPE_SMS_MESSAGE: - // it's a SMS message from a mobile - broadcast to SMS plugin - if (dwUin != 1002) { - NetLog_Uni(bThruDC, "Malformed '%s' message", "SMS Mobile"); - break; - } - debugLogA("Received SMS Mobile message"); - - ProtoBroadcastAck(NULL, ICQACKTYPE_SMS, ACKRESULT_SUCCESS, nullptr, (LPARAM)szMsg); - break; - - case MTYPE_STATUSMSGEXT: - // it's either extended StatusMsg reply from icq2003b or a IcqWebMessage - if (dwUin == 1003) - debugLogA("Received ICQWebMessage - NOT SUPPORTED"); - break; - - case MTYPE_WWP: - // format: fromname FE FE FE fromemail FE unknownbyte FE 'Sender IP: xxx.xxx.xxx.xxx' 0D 0A body - if (nMsgFields < 6) - debugLogA("Malformed '%s' message", "web pager"); - else { - // blob is: body(ASCIIZ), name(ASCIIZ), email(ASCIIZ) - size_t cbBlob = mir_strlen(pszMsgField[0]) + mir_strlen(pszMsgField[3]) + mir_strlen(pszMsgField[5]) + 3; - PBYTE pBlob, pCurBlob = pBlob = (PBYTE)_alloca(cbBlob); - mir_strcpy((char *)pCurBlob, pszMsgField[5]); pCurBlob += mir_strlen((char *)pCurBlob) + 1; - mir_strcpy((char *)pCurBlob, pszMsgField[0]); pCurBlob += mir_strlen((char *)pCurBlob) + 1; - mir_strcpy((char *)pCurBlob, pszMsgField[3]); - - AddEvent(NULL, ICQEVENTTYPE_WEBPAGER, dwTimestamp, 0, cbBlob, pBlob); - } - break; - - case MTYPE_EEXPRESS: - // format: fromname FE FE FE fromemail FE unknownbyte FE body - if (nMsgFields < 6) - debugLogA("Malformed '%s' message", "e-mail express"); - else { - // blob is: body(ASCIIZ), name(ASCIIZ), email(ASCIIZ) - size_t cbBlob = mir_strlen(pszMsgField[0]) + mir_strlen(pszMsgField[3]) + mir_strlen(pszMsgField[5]) + 3; - PBYTE pBlob, pCurBlob = pBlob = (PBYTE)_alloca(cbBlob); - mir_strcpy((char *)pCurBlob, pszMsgField[5]); pCurBlob += mir_strlen((char *)pCurBlob) + 1; - mir_strcpy((char *)pCurBlob, pszMsgField[0]); pCurBlob += mir_strlen((char *)pCurBlob) + 1; - mir_strcpy((char *)pCurBlob, pszMsgField[3]); - - AddEvent(NULL, ICQEVENTTYPE_EMAILEXPRESS, dwTimestamp, 0, cbBlob, pBlob); - } - break; - - case MTYPE_REQUESTCONTACTS: - /* it's a contacts-request */ - NetLog_Uni(bThruDC, "Received %s from %u", "Request for Contacts", dwUin); - break; - - case MTYPE_GREETINGCARD: - /* it's a greeting card */ - NetLog_Uni(bThruDC, "Received %s from %u", "Greeting Card", dwUin); - break; - - case MTYPE_SCRIPT_NOTIFY: - /* it's a xtraz notify request */ - NetLog_Uni(bThruDC, "Received %s from %u", "Xtraz Notify Request", dwUin); - handleXtrazNotify(dwUin, dwMsgID, dwMsgID2, wCookie, szMsg, wMsgLen, bThruDC); - break; - - case MTYPE_SCRIPT_INVITATION: - /* it's a xtraz invitation to session */ - NetLog_Uni(bThruDC, "Received %s from %u", "Xtraz Invitation", dwUin); - handleXtrazInvitation(dwUin, szMsg, bThruDC); - break; - - case MTYPE_SCRIPT_DATA: - /* it's a xtraz data packet */ - NetLog_Uni(bThruDC, "Received %s from %u", "Xtraz data packet", dwUin); - handleXtrazData(dwUin, szMsg, bThruDC); - break; - - case MTYPE_AUTOONLINE: - case MTYPE_AUTOAWAY: - case MTYPE_AUTOBUSY: - case MTYPE_AUTONA: - case MTYPE_AUTODND: - case MTYPE_AUTOFFC: - { - char **szMsgs = MirandaStatusToAwayMsg(AwayMsgTypeToStatus(type)); - if (szMsgs) { - struct rates_status_message_response : public rates_queue_item - { - protected: - virtual rates_queue_item* copyItem(rates_queue_item *aDest = nullptr) - { - rates_status_message_response *pDest = (rates_status_message_response*)aDest; - if (!pDest) - pDest = new rates_status_message_response(ppro, wGroup); - - pDest->bExtended = bExtended; - pDest->dwMsgID1 = dwMsgID1; - pDest->dwMsgID2 = dwMsgID2; - pDest->wCookie = wCookie; - pDest->wVersion = wVersion; - pDest->nMsgType = nMsgType; - - return rates_queue_item::copyItem(pDest); - }; - public: - rates_status_message_response(CIcqProto *ppro, WORD wGroup) : rates_queue_item(ppro, wGroup) {}; - virtual ~rates_status_message_response() {}; - - virtual void execute() - { - char **pszMsg = ppro->MirandaStatusToAwayMsg(AwayMsgTypeToStatus(nMsgType)); - if (bExtended) - ppro->icq_sendAwayMsgReplyServExt(dwUin, szUid, dwMsgID1, dwMsgID2, wCookie, wVersion, nMsgType, pszMsg); - else if (dwUin) - ppro->icq_sendAwayMsgReplyServ(dwUin, dwMsgID1, dwMsgID2, wCookie, wVersion, (BYTE)nMsgType, pszMsg); - else - ppro->debugLogA("Error: Malformed UIN in packet"); - }; - - BOOL bExtended; - DWORD dwMsgID1; - DWORD dwMsgID2; - WORD wCookie; - WORD wVersion; - int nMsgType; - }; - - WORD wGroup; - { - mir_cslock l(m_ratesMutex); - wGroup = m_rates->getGroupFromSNAC(ICQ_MSG_FAMILY, ICQ_MSG_RESPONSE); - } - - rates_status_message_response rr(this, wGroup); - rr.bExtended = (nMsgFlags & MTF_STATUS_EXTENDED) == MTF_STATUS_EXTENDED; - rr.hContact = hContact; - rr.dwUin = dwUin; - rr.szUid = szUID; - rr.dwMsgID1 = dwMsgID; - rr.dwMsgID2 = dwMsgID2; - rr.wCookie = wCookie; - rr.wVersion = wVersion; - rr.nMsgType = type; - - handleRateItem(&rr, RQT_RESPONSE); - } - } - break; - - case MTYPE_FILEREQ: // Never happens - default: - NetLog_Uni(bThruDC, "Unprocessed message type %d", type); - break; - - } - - SAFE_FREE(&szMsg); -} - -void CIcqProto::handleRecvMsgResponse(BYTE *buf, size_t wLen) -{ - DWORD dwCookie; - WORD wMessageFormat; - WORD wStatus; - WORD bMsgType = 0; - BYTE bFlags; - WORD wLength; - WORD wVersion = 0; - cookie_message_data *pCookieData = nullptr; - - DWORD dwMsgID1, dwMsgID2; - unpackLEDWord(&buf, &dwMsgID1); // Message ID - unpackLEDWord(&buf, &dwMsgID2); - wLen -= 8; - - unpackWord(&buf, &wMessageFormat); - wLen -= 2; - if (wMessageFormat != 2) { - debugLogA("SNAC(4.B) Unknown type"); - return; - } - - DWORD dwUin; - uid_str szUid; - if (!unpackUID(&buf, &wLen, &dwUin, &szUid)) - return; - - MCONTACT hContact = HContactFromUID(dwUin, szUid, nullptr); - - buf += 2; // 3. unknown - wLen -= 2; - - MCONTACT hCookieContact; - if (!FindMessageCookie(dwMsgID1, dwMsgID2, &dwCookie, &hCookieContact, &pCookieData)) { - debugLogA("SNAC(4.B) Received an ack that I did not ask for from (%u)", dwUin); - return; - } - - if (IsValidOscarTransfer((basic_filetransfer*)pCookieData)) { - // it is OFT response - handleRecvServResponseOFT(buf, wLen, dwUin, szUid, pCookieData); - return; - } - - if (!dwUin) { - // AIM cannot send this - just sanity - debugLogA("Error: Invalid UID in message response."); - return; - } - - // Length of sub chunk? - if (wLen >= 2) { - unpackLEWord(&buf, &wLength); - wLen -= 2; - } - else wLength = 0; - - if (wLength == 0x1b && pCookieData->bMessageType != MTYPE_REVERSE_REQUEST) { - // this can be v8 greeting message reply - unpackLEWord(&buf, &wVersion); - buf += 27; /* unknowns from the msg we sent */ - wLen -= 29; - - // Message sequence (SEQ2) - WORD wCookie; - unpackLEWord(&buf, &wCookie); - wLen -= 2; - - // Unknown (12 bytes) - buf += 12; - wLen -= 12; - - // Message type - unpackByte(&buf, (BYTE*)&bMsgType); - unpackByte(&buf, &bFlags); - wLen -= 2; - - // Status - unpackLEWord(&buf, &wStatus); - wLen -= 2; - - // Priority? - buf += 2; - wLen -= 2; - - if (!FindCookie(wCookie, &hCookieContact, (void**)&pCookieData)) { - // use old reliable method - debugLogA("Warning: Invalid cookie in %s from (%u)", "message response", dwUin); - - if (pCookieData->bMessageType != MTYPE_AUTOAWAY && bFlags == 3) { // most probably a broken ack of some kind (e.g. from R&Q), try to fix that - bMsgType = pCookieData->bMessageType; - bFlags = 0; - - debugLogA("Warning: Invalid message type in %s from (%u)", "message response", dwUin); - } - } - else if (bMsgType != MTYPE_PLUGIN && pCookieData->bMessageType != MTYPE_AUTOAWAY) { - // just because some clients break it... - dwCookie = wCookie; - - if (bMsgType != pCookieData->bMessageType) - debugLogA("Warning: Invalid message type in %s from (%u)", "message response", dwUin); - - bMsgType = pCookieData->bMessageType; - } - else if (pCookieData->bMessageType == MTYPE_AUTOAWAY && bMsgType != MTYPE_PLUGIN) { - if (bMsgType != pCookieData->nAckType) - debugLogA("Warning: Invalid message type in %s from (%u)", "message response", dwUin); - } - } - else { - bMsgType = pCookieData->bMessageType; - bFlags = 0; - wStatus = 0; - } - - if (hCookieContact != hContact) { - debugLogA("SNAC(4.B) Ack Contact does not match Cookie Contact(0x%x != 0x%x)", hContact, hCookieContact); - ReleaseCookie(dwCookie); // This could be a bad idea, but I think it is safe - return; - } - - if (bFlags == 3) // A status message reply - handleStatusMsgReply("SNAC(4.B) ", hContact, dwUin, bMsgType, dwCookie, (char*)(buf + 2)); - else { - // An ack of some kind - int ackType; - - if (hContact == NULL || hContact == INVALID_CONTACT_ID) { - debugLogA("SNAC(4.B) Message from unknown contact (%u)", dwUin); - ReleaseCookie(dwCookie); // This could be a bad idea, but I think it is safe - return; - } - - WORD wMsgLen; - switch (bMsgType) { - case MTYPE_FILEREQ: - // Message length - unpackLEWord(&buf, &wMsgLen); - wLen -= 2; - { - char *szMsg = (char *)_alloca(wMsgLen + 1); - szMsg[wMsgLen] = '\0'; - if (wMsgLen > 0) { - memcpy(szMsg, buf, wMsgLen); - buf += wMsgLen; - wLen -= wMsgLen; - } - handleFileAck(buf, wLen, dwUin, dwCookie, wStatus); - // No success protoack will be sent here, since all file requests - // will have been 'sent' when the server returns its ack - } - return; - - case MTYPE_PLUGIN: - if (wLength != 0x1B) { - debugLogA("Invalid Greeting %s", "message response"); - - ReleaseCookie(dwCookie); - return; - } - - debugLogA("Parsing Greeting %s", "message response"); - - // Message - unpackLEWord(&buf, &wMsgLen); - wLen -= 2; - buf += wMsgLen; - wLen -= wMsgLen; - - // This packet is malformed. Possibly a file accept from Miranda IM 0.1.2.1 - if (wLen < 20) { - ReleaseCookie(dwCookie); - return; - } - { - WORD wFunctionId; - int typeId; - if (!unpackPluginTypeId(&buf, &wLen, &typeId, &wFunctionId, FALSE)) { - ReleaseCookie(dwCookie); - return; - } - - if (wLen < 4) { - debugLogA("Error: Invalid greeting %s", "message response"); - ReleaseCookie(dwCookie); - return; - } - - // Length of remaining data - DWORD dwLengthToEnd; - unpackLEDWord(&buf, &dwLengthToEnd); - wLen -= 4; - - DWORD dwDataLen; - if (wLen >= 4 && dwLengthToEnd > 0) - unpackLEDWord(&buf, &dwDataLen); // Length of message - else - dwDataLen = 0; - - switch (typeId) { - case MTYPE_PLAIN: - if (pCookieData && pCookieData->bMessageType == MTYPE_AUTOAWAY && dwLengthToEnd >= 4) { - // ICQ 6 invented this - char *szMsg = (char*)_alloca(dwDataLen + 1); - - if (dwDataLen > 0) - memcpy(szMsg, buf, dwDataLen); - szMsg[dwDataLen] = '\0'; - handleStatusMsgReply("SNAC(4.B) ", hContact, dwUin, pCookieData->nAckType, dwCookie, szMsg); - - ReleaseCookie(dwCookie); - return; - } - ackType = ACKTYPE_MESSAGE; - break; - - case MTYPE_URL: - ackType = ACKTYPE_URL; - break; - - case MTYPE_CONTACTS: - ackType = ACKTYPE_CONTACTS; - break; - - case MTYPE_FILEREQ: - debugLogA("This is file ack"); - { - char *szMsg = (char *)_alloca(dwDataLen + 1); - - if (dwDataLen > 0) - memcpy(szMsg, buf, dwDataLen); - szMsg[dwDataLen] = '\0'; - buf += dwDataLen; - wLen -= dwDataLen; - - handleFileAck(buf, wLen, dwUin, dwCookie, wStatus); - // No success protoack will be sent here, since all file requests - // will have been 'sent' when the server returns its ack - } - return; - - case MTYPE_SCRIPT_NOTIFY: - { - char *szMsg = (char*)_alloca(dwDataLen + 1); - - if (dwDataLen > 0) - memcpy(szMsg, buf, dwDataLen); - szMsg[dwDataLen] = '\0'; - - handleXtrazNotifyResponse(hContact, (WORD)dwCookie, szMsg); - - ReleaseCookie(dwCookie); - } - return; - - case MTYPE_STATUSMSGEXT: - { // handle Away Message response (ICQ 6) - char *szMsg = (char*)SAFE_MALLOC(dwDataLen + 1); - - if (dwDataLen > 0) - memcpy(szMsg, buf, dwDataLen); - szMsg[dwDataLen] = '\0'; - szMsg = EliminateHtml(szMsg, dwDataLen); - - handleStatusMsgReply("SNAC(4.B) ", hContact, dwUin, pCookieData->nAckType, (WORD)dwCookie, szMsg); - - SAFE_FREE(&szMsg); - - ReleaseCookie(dwCookie); - } - return; - - default: - debugLogA("Error: Unknown plugin message response, type %d.", typeId); - return; - } - } - break; - - case MTYPE_PLAIN: - ackType = ACKTYPE_MESSAGE; - break; - - case MTYPE_URL: - ackType = ACKTYPE_URL; - break; - - case MTYPE_AUTHOK: - case MTYPE_AUTHDENY: - ackType = ACKTYPE_AUTHREQ; - break; - - case MTYPE_ADDED: - ackType = ACKTYPE_ADDED; - break; - - case MTYPE_CONTACTS: - ackType = ACKTYPE_CONTACTS; - break; - - case MTYPE_REVERSE_REQUEST: - { - cookie_reverse_connect *pReverse = (cookie_reverse_connect*)pCookieData; - - if (pReverse->ft) { - filetransfer *ft = (filetransfer*)pReverse->ft; - - ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0); - } - debugLogA("Reverse Connect request failed"); - // Set DC status to failed - setByte(hContact, "DCStatus", 2); - - ReleaseCookie(dwCookie); - } - return; - - case MTYPE_CHAT: - default: - debugLogA("SNAC(4.B) Unknown message type (%u) in switch", bMsgType); - return; - } - - if ((ackType == MTYPE_PLAIN && pCookieData && (pCookieData->nAckType == ACKTYPE_CLIENT)) || ackType != MTYPE_PLAIN) - ProtoBroadcastAck(hContact, ackType, ACKRESULT_SUCCESS, (HANDLE)(WORD)dwCookie, 0); - } - - ReleaseCookie(dwCookie); -} - -// A response to a CLI_SENDMSG -void CIcqProto::handleRecvServMsgError(BYTE *buf, size_t wLen, DWORD dwSequence) -{ - WORD wError; - char *pszErrorMessage; - MCONTACT hContact; - cookie_message_data *pCookieData = nullptr; - int nMessageType; - - - if (wLen < 2) - return; - - if (FindCookie((WORD)dwSequence, &hContact, (void**)&pCookieData)) { - // all packet cookies from msg family has command 0 in the queue - DWORD dwUin; - uid_str szUid; - if (getContactUid(hContact, &dwUin, &szUid)) { - // Invalid contact - FreeCookie((WORD)dwSequence); - return; - } - - // Error code - unpackWord(&buf, &wError); - - if (wError == 9 && pCookieData->bMessageType == MTYPE_AUTOAWAY) { - // we failed to request away message the normal way, try it AIM way - icq_packet packet; - - serverPacketInit(&packet, 13 + getUINLen(dwUin)); - packFNACHeader(&packet, ICQ_LOCATION_FAMILY, ICQ_LOCATION_REQ_USER_INFO, 0, (WORD)dwSequence); - packWord(&packet, 0x03); - packUIN(&packet, dwUin); - - sendServPacket(&packet); - return; - } - - // Not all of these are actually used in family 4 - // This will be moved into a special error handling function later - switch (wError) { - case 0x0002: // Server rate limit exceeded - pszErrorMessage = Translate("You are sending too fast. Wait a while and try again.\r\nSNAC(4.1) Error x02"); - break; - - case 0x0003: // Client rate limit exceeded - pszErrorMessage = Translate("You are sending too fast. Wait a while and try again.\r\nSNAC(4.1) Error x03"); - break; - - case 0x0004: // Recipient is not logged in (resend in a offline message) - if (pCookieData->bMessageType == MTYPE_PLAIN) { - if (pCookieData->isOffline) { - // offline failed - most probably to AIM contact - pszErrorMessage = Translate("The contact does not support receiving offline messages."); - break; - } - // TODO: this needs better solution - setWord(hContact, "Status", ID_STATUS_OFFLINE); - } - pszErrorMessage = Translate("The user has logged off. Select 'Retry' to send an offline message.\r\nSNAC(4.1) Error x04"); - break; - - case 0x0005: // Requested service unavailable - pszErrorMessage = Translate("The messaging service is temporarily unavailable. Wait a while and try again.\r\nSNAC(4.1) Error x05"); - break; - - case 0x0009: // Not supported by client (resend in a simpler format) - pszErrorMessage = Translate("The receiving client does not support this type of message.\r\nSNAC(4.1) Error x09"); - break; - - case 0x000A: // Refused by client - pszErrorMessage = Translate("You sent too long message. The receiving client does not support it.\r\nSNAC(4.1) Error x0A"); - break; - - case 0x000E: // Incorrect SNAC format - pszErrorMessage = Translate("The SNAC format was rejected by the server.\nSNAC(4.1) Error x0E"); - break; - - case 0x0013: // User temporarily unavailable - pszErrorMessage = Translate("The user is temporarily unavailable. Wait a while and try again.\r\nSNAC(4.1) Error x13"); - break; - - case 0x0001: // Invalid SNAC header - case 0x0006: // Requested service not defined - case 0x0007: // You sent obsolete SNAC - case 0x0008: // Not supported by server - case 0x000B: // Reply too big - case 0x000C: // Responses lost - case 0x000D: // Request denied - case 0x000F: // Insufficient rights - case 0x0010: // In local permit/deny (recipient blocked) - case 0x0011: // Sender too evil - case 0x0012: // Receiver too evil - case 0x0014: // No match - case 0x0015: // List overflow - case 0x0016: // Request ambiguous - case 0x0017: // Server queue full - case 0x0018: // Not while on AOL - default: - if (pszErrorMessage = (char*)_alloca(256)) - mir_snprintf(pszErrorMessage, 256, Translate("SNAC(4.1) SENDMSG Error (x%02x)"), wError); - break; - } - - switch (pCookieData->bMessageType) { - case MTYPE_PLAIN: - nMessageType = ACKTYPE_MESSAGE; - break; - - case MTYPE_CHAT: - nMessageType = ACKTYPE_CHAT; - break; - - case MTYPE_FILEREQ: - nMessageType = ACKTYPE_FILE; - break; - - case MTYPE_URL: - nMessageType = ACKTYPE_URL; - break; - - case MTYPE_CONTACTS: - nMessageType = ACKTYPE_CONTACTS; - break; - - default: - nMessageType = -1; - break; - } - - if (nMessageType != -1) - ProtoBroadcastAck(hContact, nMessageType, ACKRESULT_FAILED, (HANDLE)(WORD)dwSequence, (LPARAM)pszErrorMessage); - else - debugLogA("Error: Message delivery to %u failed: %s", dwUin, pszErrorMessage); - - FreeCookie((WORD)dwSequence); - - if (pCookieData->bMessageType != MTYPE_FILEREQ) - SAFE_FREE((void**)&pCookieData); - } - else { - unpackWord(&buf, &wError); - LogFamilyError(ICQ_MSG_FAMILY, wError); - } -} - -void CIcqProto::handleServerAck(BYTE *buf, size_t wLen, DWORD dwSequence) -{ - DWORD dwUin; - uid_str szUID; - WORD wChannel; - cookie_message_data *pCookieData; - - if (wLen < 13) { - debugLogA("Ignoring SNAC(4,C) Packet to short"); - return; - } - - buf += 8; // Skip first 8 bytes - wLen -= 8; - - // Message channel - unpackWord(&buf, &wChannel); - wLen -= 2; - - // Sender - if (!unpackUID(&buf, &wLen, &dwUin, &szUID)) return; - - MCONTACT hContact = HContactFromUID(dwUin, szUID, nullptr); - - if (FindCookie((WORD)dwSequence, nullptr, (void**)&pCookieData)) { - // If the user requested a full ack, the - // server ack should be ignored here. - if (pCookieData && (pCookieData->nAckType == ACKTYPE_SERVER)) { - if ((hContact != NULL) && (hContact != INVALID_CONTACT_ID)) { - int ackType; - int ackRes = ACKRESULT_SUCCESS; - - switch (pCookieData->bMessageType) { - case MTYPE_PLAIN: - ackType = ACKTYPE_MESSAGE; - break; - - case MTYPE_CONTACTS: - ackType = ACKTYPE_CONTACTS; - break; - - case MTYPE_URL: - ackType = ACKTYPE_URL; - break; - - case MTYPE_FILEREQ: - ackType = ACKTYPE_FILE; - ackRes = ACKRESULT_SENTREQUEST; - // Note 1: We are not allowed to free the cookie here because it - // contains the filetransfer struct that we will need later - // Note 2: The cookiedata is NOT a message_cookie_data*, it is a - // filetransfer*. IMPORTANT! (it's one of those silly things) - break; - - default: - ackType = -1; - debugLogA("Error: Unknown message type %d in ack", pCookieData->bMessageType); - break; - } - if (ackType != -1) - ProtoBroadcastAck(hContact, ackType, ackRes, (HANDLE)(WORD)dwSequence, 0); - - if (pCookieData->bMessageType != MTYPE_FILEREQ) - SAFE_FREE((void**)&pCookieData); // this could be a bad idea, but I think it is safe - } - FreeCookie((WORD)dwSequence); - } - else if (pCookieData && (pCookieData->nAckType == ACKTYPE_CLIENT)) - debugLogA("Received a server ack, waiting for client ack."); - else - debugLogA("Ignored a server ack I did not ask for"); - } -} - -void CIcqProto::handleMissedMsg(BYTE *buf, size_t wLen) -{ - DWORD dwUin; - uid_str szUid; - WORD wChannel; - WORD wWarningLevel; - WORD wCount; - WORD wError; - WORD wTLVCount; - - if (wLen < 14) - return; // Too short - - // Message channel? - unpackWord(&buf, &wChannel); - wLen -= 2; - - // Sender - if (!unpackUID(&buf, &wLen, &dwUin, &szUid)) return; - - if (wLen < 8) - return; // Too short - - // Warning level? - unpackWord(&buf, &wWarningLevel); - wLen -= 2; - - // TLV count - unpackWord(&buf, &wTLVCount); - wLen -= 2; - - // Read past user info TLVs - oscar_tlv_chain *pChain = readIntoTLVChain(&buf, wLen - 4, wTLVCount); - if (pChain) - disposeChain(&pChain); - - if (wLen < 4) - return; // Too short - - // Number of missed messages - unpackWord(&buf, &wCount); - wLen -= 2; - - // Error code - unpackWord(&buf, &wError); - wLen -= 2; - - { // offline retrieval process in progress, note that we received missed message notification - cookie_offline_messages *cookie; - - if (FindCookieByType(CKT_OFFLINEMESSAGE, nullptr, nullptr, (void**)&cookie)) - cookie->nMissed++; - } - - switch (wError) { - - case 0: // The message was invalid - case 1: // The message was too long - case 2: // The sender has flooded the server - case 4: // You are too evil - break; - - default: - // 3 = Sender too evil (sender warn level > your max_msg_sevil) - return; - break; - } - - // Create event to notify user - int bAdded; - - AddEvent(HContactFromUID(dwUin, szUid, &bAdded), ICQEVENTTYPE_MISSEDMESSAGE, time(0), 0, sizeof(wError), (PBYTE)&wError); -} - -void CIcqProto::handleOffineMessagesReply(DWORD dwRef) -{ - cookie_offline_messages *cookie; - - if (FindCookie(dwRef, nullptr, (void**)&cookie)) { - debugLogA("End of offline msgs, %u received", cookie->nMessages); - if (cookie->nMissed) { // NASTY WORKAROUND!! - // The ICQ server has a bug that causes offline messages to be received again and again when some - // missed message notification is present (most probably it is not processed correctly and causes - // the server to fail the purging process); try to purge them using the old offline messages - // protocol. 2008/05/21 - debugLogA("Warning: Received %u missed message notifications, trying to fix the server.", cookie->nMissed); - - icq_packet packet; - // This will delete the messages stored on server - serverPacketInit(&packet, 24); - packFNACHeader(&packet, ICQ_EXTENSIONS_FAMILY, ICQ_META_CLI_REQUEST); - packWord(&packet, 1); // TLV Type - packWord(&packet, 10); // TLV Length - packLEWord(&packet, 8); // Data length - packLEDWord(&packet, m_dwLocalUIN); // My UIN - packLEWord(&packet, CLI_DELETE_OFFLINE_MSGS_REQ); // Ack offline msgs - packLEWord(&packet, 0x0000); // Request sequence number (we dont use this for now) - - // Send it - sendServPacket(&packet); - } - - ReleaseCookie(dwRef); - } - else debugLogA("Error: Received unexpected end of offline msgs."); -} - -void CIcqProto::handleTypingNotification(BYTE *buf, size_t wLen) -{ - if (wLen < 14) { - debugLogA("Ignoring SNAC(4.x11) Packet to short"); - return; - } - - // The message ID, unused? - buf += 8; - wLen -= 8; - - // Message channel, unused? - WORD wChannel; - unpackWord(&buf, &wChannel); - wLen -= 2; - - // Sender - DWORD dwUin; - uid_str szUid; - if (!unpackUID(&buf, &wLen, &dwUin, &szUid)) - return; - - MCONTACT hContact = HContactFromUID(dwUin, szUid, nullptr); - - if (hContact == INVALID_CONTACT_ID) return; - - // Typing notification code - WORD wNotification; - unpackWord(&buf, &wNotification); - wLen -= 2; - - SetContactCapabilities(hContact, CAPF_TYPING); - - // Notify user - switch (wNotification) { - case MTN_FINISHED: - case MTN_TYPED: - CallService(MS_PROTO_CONTACTISTYPING, hContact, (LPARAM)PROTOTYPE_CONTACTTYPING_OFF); - debugLogA("%s has stopped typing (ch %u).", strUID(dwUin, szUid), wChannel); - break; - - case MTN_BEGUN: - CallService(MS_PROTO_CONTACTISTYPING, hContact, (LPARAM)60); - debugLogA("%s is typing a message (ch %u).", strUID(dwUin, szUid), wChannel); - break; - - case MTN_WINDOW_CLOSED: - { - char szFormat[MAX_PATH]; - char szMsg[MAX_PATH]; - char *nick = NickFromHandleUtf(hContact); - - mir_snprintf(szMsg, ICQTranslateUtfStatic(LPGEN("Contact \"%s\" has closed the message window."), szFormat, MAX_PATH), nick); - ShowPopupMsg(hContact, ICQTranslateUtfStatic(LPGEN("ICQ Note"), szFormat, MAX_PATH), szMsg, LOG_NOTE); - SAFE_FREE((void**)&nick); - - debugLogA("%s has closed the message window.", strUID(dwUin, szUid)); - } - break; - - default: - debugLogA("Unknown typing notification from %s, type %u (ch %u)", strUID(dwUin, szUid), wNotification, wChannel); - break; - } -} - -void CIcqProto::sendTypingNotification(MCONTACT hContact, WORD wMTNCode) -{ - _ASSERTE((wMTNCode == MTN_FINISHED) || (wMTNCode == MTN_TYPED) || (wMTNCode == MTN_BEGUN) || (wMTNCode == MTN_WINDOW_CLOSED)); - - DWORD dwUin; - uid_str szUid; - if (getContactUid(hContact, &dwUin, &szUid)) - return; // Invalid contact - - size_t wLen = getUIDLen(dwUin, szUid); - - icq_packet packet; - serverPacketInit(&packet, 23 + wLen); - packFNACHeader(&packet, ICQ_MSG_FAMILY, ICQ_MSG_MTN); - packLEDWord(&packet, 0x0000); // Msg ID - packLEDWord(&packet, 0x0000); // Msg ID - packWord(&packet, 0x01); // Channel - packUID(&packet, dwUin, szUid); // User ID - packWord(&packet, wMTNCode); // Notification type - - sendServPacketAsync(&packet); -} diff --git a/protocols/IcqOscarJ/src/fam_09bos.cpp b/protocols/IcqOscarJ/src/fam_09bos.cpp deleted file mode 100644 index 53cefff9b8..0000000000 --- a/protocols/IcqOscarJ/src/fam_09bos.cpp +++ /dev/null @@ -1,91 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2008 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -void CIcqProto::handleBosFam(unsigned char *pBuffer, size_t wBufferLength, snac_header* pSnacHeader) -{ - switch (pSnacHeader->wSubtype) { - case ICQ_PRIVACY_RIGHTS_REPLY: // Reply to CLI_REQBOS - handlePrivacyRightsReply(pBuffer, wBufferLength); - break; - - case ICQ_ERROR: - { - WORD wError; - - if (wBufferLength >= 2) - unpackWord(&pBuffer, &wError); - else - wError = 0; - - LogFamilyError(ICQ_BOS_FAMILY, wError); - break; - } - - default: - debugLogA("Warning: Ignoring SNAC(x%02x,x%02x) - Unknown SNAC (Flags: %u, Ref: %u)", ICQ_BOS_FAMILY, pSnacHeader->wSubtype, pSnacHeader->wFlags, pSnacHeader->dwRef); - break; - } -} - -void CIcqProto::handlePrivacyRightsReply(unsigned char *pBuffer, size_t wBufferLength) -{ - if (wBufferLength >= 12) { - oscar_tlv_chain* pChain = readIntoTLVChain(&pBuffer, wBufferLength, 0); - if (pChain) { - WORD wMaxVisibleContacts = pChain->getWord(0x0001, 1); - WORD wMaxInvisibleContacts = pChain->getWord(0x0002, 1); - WORD wMaxTemporaryVisibleContacts = pChain->getWord(0x0003, 1); - - disposeChain(&pChain); - - debugLogA("PRIVACY: Max visible %u, max invisible %u, max temporary visible %u items.", wMaxVisibleContacts, wMaxInvisibleContacts, wMaxTemporaryVisibleContacts); - - // Success - return; - } - } - - // Failure - debugLogA("Warning: Malformed SRV_PRIVACY_RIGHTS_REPLY"); -} - -void CIcqProto::makeContactTemporaryVisible(MCONTACT hContact) -{ - if (getByte(hContact, "TemporaryVisible", 0)) - return; // already there - - DWORD dwUin; - uid_str szUid; - if (getContactUid(hContact, &dwUin, &szUid)) - return; // Invalid contact - - icq_sendGenericContact(dwUin, szUid, ICQ_BOS_FAMILY, ICQ_CLI_ADDTEMPVISIBLE); - - setByte(hContact, "TemporaryVisible", 1); - - debugLogA("Added contact %s to temporary visible list", strUID(dwUin, szUid)); -} diff --git a/protocols/IcqOscarJ/src/fam_0alookup.cpp b/protocols/IcqOscarJ/src/fam_0alookup.cpp deleted file mode 100644 index cdce8c145b..0000000000 --- a/protocols/IcqOscarJ/src/fam_0alookup.cpp +++ /dev/null @@ -1,118 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -void CIcqProto::handleLookupFam(BYTE *pBuffer, size_t wBufferLength, snac_header* pSnacHeader) -{ - switch (pSnacHeader->wSubtype) { - - case ICQ_LOOKUP_EMAIL_REPLY: // AIM search reply - handleLookupEmailReply(pBuffer, wBufferLength, pSnacHeader->dwRef); - break; - - case ICQ_ERROR: - { - WORD wError; - if (wBufferLength >= 2) - unpackWord(&pBuffer, &wError); - else - wError = 0; - - cookie_search *pCookie; - if (FindCookie(pSnacHeader->dwRef, nullptr, (void**)&pCookie)) { - if (wError == 0x14) - debugLogA("Lookup: No results"); - - ReleaseLookupCookie(pSnacHeader->dwRef, pCookie); - - if (wError == 0x14) return; - } - - LogFamilyError(ICQ_LOOKUP_FAMILY, wError); - } - break; - - default: - debugLogA("Warning: Ignoring SNAC(x%02x,x%02x) - Unknown SNAC (Flags: %u, Ref: %u)", ICQ_LOOKUP_FAMILY, pSnacHeader->wSubtype, pSnacHeader->wFlags, pSnacHeader->dwRef); - break; - } -} - -void CIcqProto::ReleaseLookupCookie(DWORD dwCookie, cookie_search *pCookie) -{ - FreeCookie(dwCookie); - SAFE_FREE(&pCookie->szObject); - - if (pCookie->dwMainId && !pCookie->dwStatus) // we need to wait for main search - pCookie->dwStatus = 1; - else { // finish everything - if (pCookie->dwMainId) - ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)pCookie->dwMainId, 0); - else // we are single - ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)dwCookie, 0); - - SAFE_FREE((void**)&pCookie); - } -} - -void CIcqProto::handleLookupEmailReply(BYTE* buf, size_t wLen, DWORD dwCookie) -{ - ICQSEARCHRESULT sr = { 0 }; - oscar_tlv_chain *pChain; - cookie_search *pCookie; - - if (!FindCookie(dwCookie, nullptr, (void**)&pCookie)) { - debugLogA("Error: Received unexpected lookup reply"); - return; - } - - debugLogA("SNAC(0x0A,0x3): Lookup reply"); - - sr.hdr.cbSize = sizeof(sr); - sr.hdr.flags = PSR_UNICODE; - sr.hdr.email.w = ansi_to_unicode(pCookie->szObject); - - // Syntax check, read chain - if (wLen >= 4 && (pChain = readIntoTLVChain(&buf, wLen, 0))) { - for (WORD i = 1; TRUE; i++) { // collect the results - char *szUid = pChain->getString(0x01, i); - if (!szUid) break; - sr.hdr.id.w = ansi_to_unicode(szUid); - sr.hdr.nick.w = sr.hdr.id.w; - // broadcast the result - if (pCookie->dwMainId) - ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)pCookie->dwMainId, (LPARAM)&sr); - else - ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)dwCookie, (LPARAM)&sr); - SAFE_FREE(&sr.hdr.id.w); - SAFE_FREE(&szUid); - } - disposeChain(&pChain); - } - SAFE_FREE(&sr.hdr.email.w); - - ReleaseLookupCookie(dwCookie, pCookie); -} diff --git a/protocols/IcqOscarJ/src/fam_0bstatus.cpp b/protocols/IcqOscarJ/src/fam_0bstatus.cpp deleted file mode 100644 index 6f7b5d69d3..0000000000 --- a/protocols/IcqOscarJ/src/fam_0bstatus.cpp +++ /dev/null @@ -1,52 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000,2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001,2002 Jon Keating, Richard Hughes -// Copyright © 2002,2003,2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004,2005,2006 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -void CIcqProto::handleStatusFam(unsigned char *pBuffer, size_t wBufferLength, snac_header* pSnacHeader) -{ - switch (pSnacHeader->wSubtype) { - - case ICQ_STATS_MINREPORTINTERVAL: - WORD wInterval; - unpackWord(&pBuffer, &wInterval); - debugLogA("Server sent SNAC(x0B,x02) - SRV_SET_MINREPORTINTERVAL (Value: %u hours)", wInterval); - break; - - case ICQ_ERROR: - WORD wError; - if (wBufferLength >= 2) - unpackWord(&pBuffer, &wError); - else - wError = 0; - - LogFamilyError(ICQ_STATS_FAMILY, wError); - break; - - default: - debugLogA("Warning: Ignoring SNAC(x%02x,x%02x) - Unknown SNAC (Flags: %u, Ref: %u)", ICQ_STATS_FAMILY, pSnacHeader->wSubtype, pSnacHeader->wFlags, pSnacHeader->dwRef); - break; - } -} diff --git a/protocols/IcqOscarJ/src/fam_13servclist.cpp b/protocols/IcqOscarJ/src/fam_13servclist.cpp deleted file mode 100644 index c3dcf0a02d..0000000000 --- a/protocols/IcqOscarJ/src/fam_13servclist.cpp +++ /dev/null @@ -1,1720 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -static int unpackServerListItem(BYTE **pbuf, size_t *pwLen, char *pszRecordName, WORD *pwGroupId, WORD *pwItemId, WORD *pwItemType, size_t *pwTlvLength); - -void CIcqProto::handleServCListFam(BYTE *pBuffer, size_t wBufferLength, snac_header* pSnacHeader, serverthread_info *info) -{ - switch (pSnacHeader->wSubtype) { - case ICQ_LISTS_ACK: // UPDATE_ACK - if (wBufferLength >= 2) { - WORD wError; - unpackWord(&pBuffer, &wError); - - cookie_servlist_action *sc; - if (FindCookie(pSnacHeader->dwRef, nullptr, (void**)&sc)) { // look for action cookie - debugLogA("Received expected server list ack, action: %d, result: %d", sc->dwAction, wError); - FreeCookie(pSnacHeader->dwRef); // release cookie - - if (sc->dwAction == SSA_ACTION_GROUP) { // group cookie, handle sub-items - int i; - - debugLogA("Server-List: Grouped action contains %d actions.", sc->dwGroupCount); - - pBuffer -= 2; // revoke unpack - if ((int)wBufferLength != 2 * sc->dwGroupCount) - debugLogA("Error: Server list ack does not contain expected amount of result codes (%u != %u)", wBufferLength / 2, sc->dwGroupCount); - - for (i = 0; i < sc->dwGroupCount; i++) { - if (wBufferLength >= 2) { // get proper result code - unpackWord(&pBuffer, &wError); - wBufferLength -= 2; - } - else // missing result code, give some special - wError = -1; - - debugLogA("Action: %d, ack result: %d", sc->pGroupItems[i]->dwAction, wError); - - // call normal ack handler - handleServerCListAck(sc->pGroupItems[i], wError); - } - // Release cookie - SAFE_FREE((void**)&sc->pGroupItems); - SAFE_FREE((void**)&sc); - } - else // single ack - handleServerCListAck(sc, wError); - } - else debugLogA("Received unexpected server list ack %u", wError); - } - break; - - case ICQ_LISTS_SRV_REPLYLISTS: - /* received server-list rights */ - handleServerCListRightsReply(pBuffer, wBufferLength); - debugLogA("Server sent SNAC(x13,x03) - SRV_REPLYLISTS"); - break; - - case ICQ_LISTS_LIST: // SRV_REPLYROSTER - { - cookie_servlist_action* sc; - BOOL blWork = bIsSyncingCL; - bIsSyncingCL = TRUE; // this is not used if cookie takes place - - if (FindCookie(pSnacHeader->dwRef, nullptr, (void**)&sc)) { // we do it by reliable cookie - if (!sc->lParam) { // is this first packet ? - ResetSettingsOnListReload(); - sc->lParam = 1; - } - handleServerCListReply(pBuffer, wBufferLength, pSnacHeader->wFlags, info); - if (!(pSnacHeader->wFlags & 0x0001)) // was that last packet ? - ReleaseCookie(pSnacHeader->dwRef); // yes, release cookie - } - else { // use old fake - if (!blWork) // this can fail on some crazy situations - ResetSettingsOnListReload(); - - handleServerCListReply(pBuffer, wBufferLength, pSnacHeader->wFlags, info); - } - } - break; - - case ICQ_LISTS_UPTODATE: // SRV_REPLYROSTEROK - bIsSyncingCL = FALSE; - { - cookie_servlist_action* sc; - if (FindCookie(pSnacHeader->dwRef, nullptr, (void**)&sc)) { // we requested servlist check - debugLogA("Server stated roster is ok."); - ReleaseCookie(pSnacHeader->dwRef); - LoadServerIDs(); - } - else debugLogA("Server sent unexpected SNAC(x13,x0F) - SRV_REPLYROSTEROK"); - - // This will activate the server side list - sendRosterAck(); // this must be here, cause of failures during cookie alloc - handleServUINSettings(wListenPort, info); - } - break; - - case ICQ_LISTS_CLI_MODIFYSTART: - debugLogA("Server sent SNAC(x13,x%02x) - %s", ICQ_LISTS_CLI_MODIFYSTART, "Server is modifying contact list"); - break; - - case ICQ_LISTS_CLI_MODIFYEND: - debugLogA("Server sent SNAC(x13,x%02x) - %s", ICQ_LISTS_CLI_MODIFYEND, "End of server modification"); - break; - - case ICQ_LISTS_ADDTOLIST: - case ICQ_LISTS_UPDATEGROUP: - case ICQ_LISTS_REMOVEFROMLIST: - { - int nItems = 0; - - while (wBufferLength >= 10) { - WORD wGroupId, wItemId, wItemType; - size_t wTlvLen; - uid_str szRecordName; - - if (unpackServerListItem(&pBuffer, &wBufferLength, szRecordName, &wGroupId, &wItemId, &wItemType, &wTlvLen)) { - BYTE *buf = pBuffer; - oscar_tlv_chain *pChain = nullptr; - - nItems++; - - // parse possible item's data - if (wBufferLength >= wTlvLen && wTlvLen > 0) { - pChain = readIntoTLVChain(&buf, wTlvLen, 0); - pBuffer += wTlvLen; - wBufferLength -= wTlvLen; - } - else if (wTlvLen > 0) - wBufferLength = 0; - - // process item change - if (pSnacHeader->wSubtype == ICQ_LISTS_ADDTOLIST) - handleServerCListItemAdd(wItemId, wItemType, pChain); - else if (pSnacHeader->wSubtype == ICQ_LISTS_UPDATEGROUP) - handleServerCListItemUpdate(szRecordName, wItemType, pChain); - else if (pSnacHeader->wSubtype == ICQ_LISTS_REMOVEFROMLIST) - handleServerCListItemDelete(szRecordName, wItemId, wItemType); - - // release memory - disposeChain(&pChain); - } - } - - // log packet basics - char *szChange; - - if (pSnacHeader->wSubtype == ICQ_LISTS_ADDTOLIST) - szChange = "Server added %u item(s) to list"; - else if (pSnacHeader->wSubtype == ICQ_LISTS_UPDATEGROUP) - szChange = "Server updated %u item(s) on list"; - else if (pSnacHeader->wSubtype == ICQ_LISTS_REMOVEFROMLIST) - szChange = "Server removed %u item(s) from list"; - else - break; - - char szLogText[MAX_PATH]; - mir_snprintf(szLogText, szChange, nItems); - debugLogA("Server sent SNAC(x13,x%02x) - %s", pSnacHeader->wSubtype, szLogText); - } - break; - - case ICQ_LISTS_AUTHREQUEST: - handleRecvAuthRequest(pBuffer, wBufferLength); - break; - - case ICQ_LISTS_SRV_AUTHRESPONSE: - handleRecvAuthResponse(pBuffer, wBufferLength); - break; - - case ICQ_LISTS_AUTHGRANTED: - debugLogA("Server sent SNAC(x13,x%02x) - %s", ICQ_LISTS_AUTHGRANTED, "User granted us future authorization"); - break; - - case ICQ_LISTS_YOUWEREADDED: - handleRecvAdded(pBuffer, wBufferLength); - break; - - case ICQ_LISTS_ERROR: - if (wBufferLength >= 2) { - WORD wError; - cookie_servlist_action* sc; - - unpackWord(&pBuffer, &wError); - - if (FindCookie(pSnacHeader->dwRef, nullptr, (void**)&sc)) { // look for action cookie - debugLogA("Received server list error, action: %d, result: %d", sc->dwAction, wError); - FreeCookie(pSnacHeader->dwRef); // release cookie - - if (sc->dwAction == SSA_CHECK_ROSTER) { // the serv-list is unavailable turn it off - icq_LogMessage(LOG_ERROR, LPGEN("Server contact list is unavailable, Miranda will use local contact list.")); - m_bSsiEnabled = 0; - handleServUINSettings(wListenPort, info); - } - /// FIXME: properly release pending operations & cookie memory - SAFE_FREE((void**)&sc); - } - else LogFamilyError(ICQ_LISTS_FAMILY, wError); - } - break; - - default: - debugLogA("Warning: Ignoring SNAC(x%02x,x%02x) - Unknown SNAC (Flags: %u, Ref: %u)", ICQ_LISTS_FAMILY, pSnacHeader->wSubtype, pSnacHeader->wFlags, pSnacHeader->dwRef); - break; - } -} - - -static int unpackServerListItem(BYTE **pbuf, size_t *pwLen, char *pszRecordName, WORD *pwGroupId, WORD *pwItemId, WORD *pwItemType, size_t *pwTlvLength) -{ - size_t wRecordNameLen; - - // The name of the entry. If this is a group header, then this - // is the name of the group. If it is a plain contact list entry, - // then it's the UIN of the contact. - unpackWord(pbuf, &wRecordNameLen); - if (*pwLen < 10 + wRecordNameLen || wRecordNameLen >= MAX_PATH) - return 0; // Failure - - unpackString(pbuf, pszRecordName, wRecordNameLen); - if (pszRecordName) - pszRecordName[wRecordNameLen] = '\0'; - - // The group identifier this entry belongs to. If 0, this is meta information or - // a contact without a group - unpackWord(pbuf, pwGroupId); - - // The ID of this entry. Group headers have ID 0. Otherwise, this - // is a random number generated when the user is added to the - // contact list, or when the user is ignored. See CLI_ADDBUDDY. - unpackWord(pbuf, pwItemId); - - // This field indicates what type of entry this is - unpackWord(pbuf, pwItemType); - - // The length in bytes of the following TLV chain - unpackWord(pbuf, pwTlvLength); - - *pwLen -= wRecordNameLen + 10; - - return 1; // Success -} - - -void CIcqProto::handleServerCListRightsReply(BYTE *buf, size_t wLen) -{ - /* received list rights, store the item limits for future use */ - oscar_tlv_chain* chain; - - memset(m_wServerListLimits, -1, sizeof(m_wServerListLimits)); - m_wServerListGroupMaxContacts = 0; - m_wServerListRecordNameMaxLength = 0xFFFF; - - if (chain = readIntoTLVChain(&buf, wLen, 0)) { - // determine max number of contacts in a group - m_wServerListGroupMaxContacts = chain->getWord(0x0C, 1); - // determine length limit for server-list item's name - m_wServerListRecordNameMaxLength = chain->getWord(0x06, 1); - - if (oscar_tlv *pTLV = chain->getTLV(0x04, 1)) { // limits for item types - WORD *pLimits = (WORD*)pTLV->pData; - for (int i = 0; i < pTLV->wLen / 2; i++) { - m_wServerListLimits[i] = (pLimits[i] & 0xFF) << 8 | (pLimits[i] >> 8); - - if (i + 1 >= _countof(m_wServerListLimits)) - break; - } - - debugLogA("SSI: Max %d contacts (%d per group), %d groups, %d permit, %d deny, %d ignore items.", m_wServerListLimits[SSI_ITEM_BUDDY], m_wServerListGroupMaxContacts, m_wServerListLimits[SSI_ITEM_GROUP], m_wServerListLimits[SSI_ITEM_PERMIT], m_wServerListLimits[SSI_ITEM_DENY], m_wServerListLimits[SSI_ITEM_IGNORE]); - } - - disposeChain(&chain); - } -} - -DWORD CIcqProto::updateServerGroupData(WORD wGroupId, void *groupData, int groupSize, DWORD dwOperationFlags) -{ - cookie_servlist_action* ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action)); - if (!ack) { - debugLogA("Updating of group on server list failed (malloc error)"); - return 0; - } - ack->dwAction = SSA_GROUP_UPDATE; - ack->szGroupName = getServListGroupName(wGroupId); - ack->wGroupId = wGroupId; - - DWORD dwCookie = AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_UPDATEGROUP, 0, ack); - return icq_sendServerGroup(dwCookie, ICQ_LISTS_UPDATEGROUP, ack->wGroupId, ack->szGroupName, groupData, groupSize, dwOperationFlags); -} - -void CIcqProto::handleServerCListAck(cookie_servlist_action* sc, WORD wError) -{ - switch (sc->dwAction) { - case SSA_VISIBILITY: - if (wError) - debugLogA("Server visibility update failed, error %d", wError); - break; - - case SSA_CONTACT_UPDATE: - servlistPendingRemoveContact(sc->hContact, sc->wContactId, sc->wGroupId, wError ? PENDING_RESULT_FAILED : PENDING_RESULT_SUCCESS); - if (wError) { - debugLogA("Updating of server contact failed, error %d", wError); - icq_LogMessage(LOG_WARNING, LPGEN("Updating of server contact failed.")); - } - break; - - case SSA_PRIVACY_ADD: - if (wError) { - debugLogA("Adding of privacy item to server list failed, error %d", wError); - icq_LogMessage(LOG_WARNING, LPGEN("Adding of privacy item to server list failed.")); - } - break; - - case SSA_PRIVACY_REMOVE: - if (wError) { - debugLogA("Removing of privacy item from server list failed, error %d", wError); - icq_LogMessage(LOG_WARNING, LPGEN("Removing of privacy item from server list failed.")); - } - FreeServerID(sc->wContactId, SSIT_ITEM); // release server id - break; - - case SSA_CONTACT_ADD: - if (wError) { - if (wError == 0xE) { // server refused to add contact w/o auth, add with - debugLogA("Contact could not be added without authorization, add with await auth flag."); - - setByte(sc->hContact, "Auth", 1); // we need auth - DWORD dwCookie = AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_ADDTOLIST, sc->hContact, sc); - icq_sendServerContact(sc->hContact, dwCookie, ICQ_LISTS_ADDTOLIST, sc->wGroupId, sc->wContactId, SSOP_ITEM_ACTION | SSOF_CONTACT, 500, nullptr); - - sc = nullptr; // we do not want it to be freed now - break; - } - FreeServerID(sc->wContactId, SSIT_ITEM); - - debugLogA("Adding of contact to server list failed, error %d", wError); - icq_LogMessage(LOG_WARNING, LPGEN("Adding of contact to server list failed.")); - - servlistPendingRemoveContact(sc->hContact, 0, sc->wGroupId, PENDING_RESULT_FAILED); - - servlistPostPacket(nullptr, 0, SSO_END_OPERATION, 100); // end server modifications here - } - else { - void* groupData; - int groupSize; - - setWord(sc->hContact, DBSETTING_SERVLIST_ID, sc->wContactId); - setWord(sc->hContact, DBSETTING_SERVLIST_GROUP, sc->wGroupId); - - servlistPendingRemoveContact(sc->hContact, sc->wContactId, sc->wGroupId, PENDING_RESULT_SUCCESS); - - if (groupData = collectBuddyGroup(sc->wGroupId, &groupSize)) { // the group is not empty, just update it - updateServerGroupData(sc->wGroupId, groupData, groupSize, SSOF_END_OPERATION); - SAFE_FREE((void**)&groupData); - } - else { // this should never happen - debugLogA("Group update failed."); - servlistPostPacket(nullptr, 0, SSO_END_OPERATION, 100); // end server modifications here - } - } - break; - - case SSA_GROUP_ADD: - if (wError) { - FreeServerID(sc->wGroupId, SSIT_GROUP); - debugLogA("Adding of group to server list failed, error %d", wError); - icq_LogMessage(LOG_WARNING, LPGEN("Adding of group to server list failed.")); - - servlistPendingRemoveGroup(sc->szGroup, 0, PENDING_RESULT_FAILED); - } - else { // group added, we need to update master group - void* groupData; - int groupSize; - - setServListGroupName(sc->wGroupId, sc->szGroupName); // add group to namelist - { // add group to known - char *szCListGroup = getServListGroupCListPath(sc->wGroupId); - - // create link to the original CList group - setServListGroupLinkID(sc->szGroup, sc->wGroupId); - - servlistPendingRemoveGroup(sc->szGroup, sc->wGroupId, PENDING_RESULT_SUCCESS); - SAFE_FREE((void**)&szCListGroup); - } - - groupData = collectGroups(&groupSize); - groupData = SAFE_REALLOC(groupData, groupSize + 2); - *(((WORD*)groupData) + (groupSize >> 1)) = sc->wGroupId; // add this new group id - groupSize += 2; - - cookie_servlist_action *ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action)); - if (ack) { - ack->dwAction = SSA_GROUP_UPDATE; - - DWORD dwCookie = AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_UPDATEGROUP, 0, ack); - icq_sendServerGroup(dwCookie, ICQ_LISTS_UPDATEGROUP, 0, ack->szGroupName, groupData, groupSize, SSOF_END_OPERATION); - } - else // end server modifications here - servlistPostPacket(nullptr, 0, SSO_END_OPERATION, 100); - - SAFE_FREE((void**)&groupData); - } - if (sc->szGroup != sc->szGroupName) - SAFE_FREE((void**)&sc->szGroup); - - SAFE_FREE((void**)&sc->szGroupName); - break; - - case SSA_CONTACT_REMOVE: - if (!wError) { - void* groupData; - int groupSize; - - setWord(sc->hContact, DBSETTING_SERVLIST_ID, 0); // clear the values - setWord(sc->hContact, DBSETTING_SERVLIST_GROUP, 0); - - FreeServerID(sc->wContactId, SSIT_ITEM); - - servlistPendingRemoveContact(sc->hContact, 0, sc->wGroupId, PENDING_RESULT_SUCCESS); - - if (groupData = collectBuddyGroup(sc->wGroupId, &groupSize)) { // the group is still not empty, just update it - updateServerGroupData(sc->wGroupId, groupData, groupSize, SSOF_END_OPERATION); - } - else // the group is empty, delete it - { - char *szGroup = getServListGroupCListPath(sc->wGroupId); - - servlistRemoveGroup(szGroup, sc->wGroupId); - SAFE_FREE((void**)&szGroup); - } - SAFE_FREE((void**)&groupData); // free the memory - } - else { - debugLogA("Removing of contact from server list failed, error %d", wError); - icq_LogMessage(LOG_WARNING, LPGEN("Removing of contact from server list failed.")); - - servlistPendingRemoveContact(sc->hContact, sc->wContactId, sc->wGroupId, PENDING_RESULT_FAILED); - - servlistPostPacket(nullptr, 0, SSO_END_OPERATION, 100); // end server modifications here - } - break; - - case SSA_GROUP_UPDATE: - if (wError) { - debugLogA("Updating of group on server list failed, error %d", wError); - icq_LogMessage(LOG_WARNING, LPGEN("Updating of group on server list failed.")); - } - SAFE_FREE((void**)&sc->szGroupName); - break; - - case SSA_GROUP_REMOVE: - SAFE_FREE((void**)&sc->szGroupName); - if (wError) { - debugLogA("Removing of group from server list failed, error %d", wError); - icq_LogMessage(LOG_WARNING, LPGEN("Removing of group from server list failed.")); - - servlistPendingRemoveGroup(sc->szGroup, 0, PENDING_RESULT_FAILED); - - servlistPostPacket(nullptr, 0, SSO_END_OPERATION, 100); // end server modifications here - SAFE_FREE((void**)&sc->szGroup); - } - else { // group removed, we need to update master group - void* groupData; - int groupSize; - - setServListGroupName(sc->wGroupId, nullptr); // clear group from namelist - FreeServerID(sc->wGroupId, SSIT_GROUP); - removeGroupPathLinks(sc->wGroupId); - - servlistPendingRemoveGroup(sc->szGroup, 0, PENDING_RESULT_SUCCESS); - SAFE_FREE((void**)&sc->szGroup); - - groupData = collectGroups(&groupSize); - sc->wGroupId = 0; - sc->dwAction = SSA_GROUP_UPDATE; - sc->szGroupName = nullptr; - DWORD dwCookie = AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_UPDATEGROUP, 0, sc); - - icq_sendServerGroup(dwCookie, ICQ_LISTS_UPDATEGROUP, 0, sc->szGroupName, groupData, groupSize, SSOF_END_OPERATION); - // end server modifications here - - sc = nullptr; // we do not want to be freed here - - SAFE_FREE((void**)&groupData); - } - break; - - case SSA_CONTACT_SET_GROUP: - // we moved contact to another group - if (sc->lParam == -1) // the first was an error - break; - - if (wError) { - if (wError == 0x0E && sc->lParam == 1) { // second ack - adding failed with error 0x0E, try to add with AVAIT_AUTH flag - if (!getByte(sc->hContact, "Auth", 0)) { // we tried without AWAIT_AUTH, try again with it - debugLogA("Contact could not be added without authorization, add with await auth flag."); - setByte(sc->hContact, "Auth", 1); // we need auth - } - else { // we tried with AWAIT_AUTH, try again without - debugLogA("Contact count not be added awaiting authorization, try authorized."); - setByte(sc->hContact, "Auth", 0); - } - DWORD dwCookie = AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_ADDTOLIST, sc->hContact, sc); - icq_sendServerContact(sc->hContact, dwCookie, ICQ_LISTS_ADDTOLIST, sc->wNewGroupId, sc->wNewContactId, SSOP_ITEM_ACTION | SSOF_CONTACT, 400, nullptr); - - sc->lParam = 2; // do not cycle - sc = nullptr; // we do not want to be freed here - break; - } - FreeServerID(sc->wNewContactId, SSIT_ITEM); - debugLogA("Moving of user to another group on server list failed, error %d", wError); - icq_LogMessage(LOG_ERROR, LPGEN("Moving of user to another group on server list failed.")); - - servlistPendingRemoveContact(sc->hContact, 0, (WORD)(sc->lParam ? sc->wGroupId : sc->wNewGroupId), PENDING_RESULT_FAILED); - - servlistPostPacket(nullptr, 0, SSO_END_OPERATION, 100); // end server modifications here - - if (!sc->lParam) { // is this first ack ? - sc->lParam = -1; - sc = nullptr; // this can't be freed here - } - break; - } - - if (sc->lParam) { // is this the second ack ? - void* groupData; - int groupSize; - int bEnd = 1; // shall we end the sever modifications - - setWord(sc->hContact, DBSETTING_SERVLIST_ID, sc->wNewContactId); - setWord(sc->hContact, DBSETTING_SERVLIST_GROUP, sc->wNewGroupId); - - servlistPendingRemoveContact(sc->hContact, sc->wNewContactId, sc->wNewGroupId, PENDING_RESULT_SUCCESS); - - if (groupData = collectBuddyGroup(sc->wGroupId, &groupSize)) // update the group we moved from - { // the group is still not empty, just update it - updateServerGroupData(sc->wGroupId, groupData, groupSize, 0); - SAFE_FREE((void**)&groupData); // free the memory - } - else { // the group is empty, delete it - char* szGroup = getServListGroupCListPath(sc->wGroupId); - - servlistRemoveGroup(szGroup, sc->wGroupId); - SAFE_FREE((void**)&szGroup); - bEnd = 0; // here the modifications go on - } - - groupData = collectBuddyGroup(sc->wNewGroupId, &groupSize); // update the group we moved to - updateServerGroupData(sc->wNewGroupId, groupData, groupSize, bEnd ? SSOF_END_OPERATION : 0); - // end server modifications here - SAFE_FREE((void**)&groupData); - - } - else // contact was deleted from server-list - { - delSetting(sc->hContact, DBSETTING_SERVLIST_ID); - delSetting(sc->hContact, DBSETTING_SERVLIST_GROUP); - FreeServerID(sc->wContactId, SSIT_ITEM); // release old contact id - sc->lParam = 1; - sc = nullptr; // wait for second ack - } - break; - - case SSA_CONTACT_FIX_AUTH: - if (wError) { // FIXME: something failed, we should handle it properly - } - break; - - case SSA_GROUP_RENAME: - if (wError) { - debugLogA("Renaming of server group failed, error %d", wError); - icq_LogMessage(LOG_WARNING, LPGEN("Renaming of server group failed.")); - - servlistPendingRemoveGroup(sc->szGroup, sc->wGroupId, PENDING_RESULT_FAILED); - } - else { - setServListGroupName(sc->wGroupId, sc->szGroupName); - removeGroupPathLinks(sc->wGroupId); - { // add group to known - char *szCListGroup = getServListGroupCListPath(sc->wGroupId); - - /// FIXME: need to create link to the new group name before unique item name correction as well - setServListGroupLinkID(szCListGroup, sc->wGroupId); - SAFE_FREE((void**)&szCListGroup); - } - servlistPendingRemoveGroup(sc->szGroup, sc->wGroupId, PENDING_RESULT_SUCCESS); - } - SAFE_FREE((void**)&sc->szGroupName); - SAFE_FREE((void**)&sc->szGroup); - break; - - case SSA_SETAVATAR: - if (wError) { - debugLogA("Uploading of avatar hash failed."); - if (sc->wGroupId) { // is avatar added or updated? - FreeServerID(sc->wContactId, SSIT_ITEM); - delSetting(DBSETTING_SERVLIST_AVATAR); // to fix old versions - } - } - else setWord(DBSETTING_SERVLIST_AVATAR, sc->wContactId); - break; - - case SSA_REMOVEAVATAR: - if (wError) - debugLogA("Removing of avatar hash failed."); - else { - FreeServerID(sc->wContactId, SSIT_ITEM); - delSetting(DBSETTING_SERVLIST_AVATAR); - } - break; - - case SSA_SERVLIST_ACK: - ProtoBroadcastAck(sc->hContact, ICQACKTYPE_SERVERCLIST, wError ? ACKRESULT_FAILED : ACKRESULT_SUCCESS, (HANDLE)sc->lParam, wError); - break; - - case SSA_IMPORT: - if (wError) - debugLogA("Re-starting import sequence failed, error %d", wError); - else { - setWord("SrvImportID", 0); - delSetting("ImportTS"); - } - break; - - default: - debugLogA("Server ack cookie type (%d) not recognized.", sc->dwAction); - } - - SAFE_FREE((void**)&sc); // free the memory - return; -} - -MCONTACT CIcqProto::HContactFromRecordName(const char* szRecordName, int *bAdded) -{ - MCONTACT hContact = INVALID_CONTACT_ID; - - if (!IsStringUIN(szRecordName)) // probably AIM contact - hContact = HContactFromUID(0, szRecordName, bAdded); - else { // this should be ICQ number - DWORD dwUin = atoi(szRecordName); - hContact = HContactFromUIN(dwUin, bAdded); - } - return hContact; -} - -int CIcqProto::getServerDataFromItemTLV(oscar_tlv_chain* pChain, unsigned char *buf) /// FIXME: need to keep original order -{ - // get server-list item's TLV data - oscar_tlv_chain* list = pChain; - int datalen = 0; - icq_packet pBuf; - - // Initialize our handy data buffer - pBuf.wPlace = 0; - pBuf.pData = buf; - - while (list) { // collect non-standard TLVs and save them to DB - if (list->tlv.wType != SSI_TLV_AWAITING_AUTH && - list->tlv.wType != SSI_TLV_NAME && - list->tlv.wType != SSI_TLV_COMMENT && - list->tlv.wType != SSI_TLV_METAINFO_TOKEN && - list->tlv.wType != SSI_TLV_METAINFO_TIME) { // only TLVs which we do not handle on our own - packTLV(&pBuf, list->tlv.wType, list->tlv.wLen, list->tlv.pData); - - datalen += list->tlv.wLen + 4; - } - list = list->next; - } - return datalen; -} - -void CIcqProto::handleServerCListReply(BYTE *buf, size_t wLen, WORD wFlags, serverthread_info *info) -{ - BYTE bySSIVersion; - WORD wRecordCount; - WORD wRecord; - WORD wGroupId; - WORD wItemId; - WORD wTlvType; - size_t wTlvLength; - BOOL bIsLastPacket; - uid_str szRecordName; - oscar_tlv_chain* pChain = nullptr; - oscar_tlv* pTLV = nullptr; - char *szActiveSrvGroup = nullptr; - WORD wActiveSrvGroupId = -1; - - // If flag bit 1 is set, this is not the last - // packet. If it is 0, this is the last packet - // and there will be a timestamp at the end. - if (wFlags & 0x0001) - bIsLastPacket = FALSE; - else - bIsLastPacket = TRUE; - - if (wLen < 3) - return; - - // Version number of SSI protocol? - unpackByte(&buf, &bySSIVersion); - wLen -= 1; - - // Total count of following entries. This is the size of the server - // side contact list and should be saved and sent with CLI_CHECKROSTER. - // NOTE: When the entries are split up in several packets, each packet - // has it's own count and they must be added to get the total size of - // server list. - unpackWord(&buf, &wRecordCount); - wLen -= 2; - debugLogA("SSI: number of entries is %u, version is %u", wRecordCount, bySSIVersion); - - // Loop over all items in the packet - for (wRecord = 0; wRecord < wRecordCount; wRecord++) { - debugLogA("SSI: parsing record %u", wRecord + 1); - - if (wLen < 10) { // minimum: name length (zero), group ID, item ID, empty TLV - debugLogA("Warning: SSI parsing error (%d)", 0); - break; - } - - if (!unpackServerListItem(&buf, &wLen, szRecordName, &wGroupId, &wItemId, &wTlvType, &wTlvLength)) { // unpack basic structure - debugLogA("Warning: SSI parsing error (%d)", 1); - break; - } - - debugLogA("Name: '%s', GroupID: %u, EntryID: %u, EntryType: %u, TLVlength: %u", - szRecordName, wGroupId, wItemId, wTlvType, wTlvLength); - - if (wLen < wTlvLength) { - debugLogA("Warning: SSI parsing error (%d)", 2); - break; - } - - // Initialize the tlv chain - if (wTlvLength > 0) { - pChain = readIntoTLVChain(&buf, wTlvLength, 0); - wLen -= wTlvLength; - } - else pChain = nullptr; - - switch (wTlvType) { - case SSI_ITEM_BUDDY: - { - /* this is a contact */ - int bAdded; - MCONTACT hContact = HContactFromRecordName(szRecordName, &bAdded); - - if (hContact != INVALID_CONTACT_ID) { - int bRegroup = 0; - int bNicked = 0; - - if (bAdded) { // Not already on list: added - debugLogA("SSI added new %s contact '%s'", "ICQ", szRecordName); - - AddJustAddedContact(hContact); - } - else { // we should add new contacts and this contact was just added, show it - if (IsContactJustAdded(hContact)) { - setContactHidden(hContact, 0); - bAdded = 1; // we want details for new contacts - } - else debugLogA("SSI ignoring existing contact '%s'", szRecordName); - - // Contact on server is always on list - db_set_b(hContact, "CList", "NotOnList", 0); - } - - // Save group and item ID - setWord(hContact, DBSETTING_SERVLIST_ID, wItemId); - setWord(hContact, DBSETTING_SERVLIST_GROUP, wGroupId); - ReserveServerID(wItemId, SSIT_ITEM, 0); - - if (!bAdded && getByte("LoadServerDetails", DEFAULT_SS_LOAD)) { // check if the contact has been moved on the server - if (wActiveSrvGroupId != wGroupId || !szActiveSrvGroup) { - SAFE_FREE(&szActiveSrvGroup); - szActiveSrvGroup = getServListGroupCListPath(wGroupId); - wActiveSrvGroupId = wGroupId; - } - char *szLocalGroup = getContactCListGroup(hContact); - - if (!mir_strlen(szLocalGroup)) { // no CListGroup - SAFE_FREE(&szLocalGroup); - - szLocalGroup = null_strdup(DEFAULT_SS_GROUP); - } - - if (mir_strcmp(szActiveSrvGroup, szLocalGroup) && - (mir_strlen(szActiveSrvGroup) >= mir_strlen(szLocalGroup) || (szActiveSrvGroup && _strnicmp(szActiveSrvGroup, szLocalGroup, mir_strlen(szLocalGroup))))) { // contact moved to new group or sub-group or not to master group - bRegroup = 1; - } - if (bRegroup && !mir_strcmpi(DEFAULT_SS_GROUP, szActiveSrvGroup)) /// TODO: invent something more clever for "root" group - { // is it the default "General" group ? - bRegroup = 0; // if yes, do not move to it - cause it would hide the contact - } - SAFE_FREE(&szLocalGroup); - } - - if (bRegroup || bAdded) { // if we should load server details or contact was just added, update its group - if (wActiveSrvGroupId != wGroupId || !szActiveSrvGroup) { - SAFE_FREE(&szActiveSrvGroup); - szActiveSrvGroup = getServListGroupCListPath(wGroupId); - wActiveSrvGroupId = wGroupId; - } - - if (szActiveSrvGroup) { // try to get Miranda Group path from groupid, if succeeded save to db - moveContactToCListGroup(hContact, szActiveSrvGroup); - } - } - - if (pChain) { // Look for nickname TLV and copy it to the db if necessary - if (pTLV = pChain->getTLV(SSI_TLV_NAME, 1)) { - if (pTLV->pData && (pTLV->wLen > 0)) { - char *pszNick; - WORD wNickLength; - - wNickLength = pTLV->wLen; - - pszNick = (char*)SAFE_MALLOC(wNickLength + 1); - // Copy buffer to utf-8 buffer - memcpy(pszNick, pTLV->pData, wNickLength); - pszNick[wNickLength] = 0; // Terminate string - - debugLogA("Nickname is '%s'", pszNick); - - bNicked = 1; - - // Write nickname to database - if (getByte("LoadServerDetails", DEFAULT_SS_LOAD) || bAdded) { // if just added contact, save details always - does no harm - char *szOldNick; - - if (szOldNick = getSettingStringUtf(hContact, "CList", "MyHandle", nullptr)) { - if ((mir_strcmp(szOldNick, pszNick)) && (mir_strlen(pszNick) > 0)) { // check if the truncated nick changed, i.e. do not overwrite locally stored longer nick - if (mir_strlen(szOldNick) <= mir_strlen(pszNick) || strncmp(szOldNick, pszNick, null_strcut(szOldNick, MAX_SSI_TLV_NAME_SIZE))) { - // Yes, we really do need to delete it first. Otherwise the CLUI nick - // cache isn't updated (I'll look into it) - db_unset(hContact, "CList", "MyHandle"); - db_set_utf(hContact, "CList", "MyHandle", pszNick); - } - } - SAFE_FREE(&szOldNick); - } - else if (mir_strlen(pszNick) > 0) { - db_unset(hContact, "CList", "MyHandle"); - db_set_utf(hContact, "CList", "MyHandle", pszNick); - } - } - SAFE_FREE(&pszNick); - } - else debugLogA("Invalid nickname"); - } - if (bAdded && !bNicked) - icq_QueueUser(hContact); // queue user without nick for fast auto info update - - // Look for comment TLV and copy it to the db if necessary - if (pTLV = pChain->getTLV(SSI_TLV_COMMENT, 1)) { - if (pTLV->pData && (pTLV->wLen > 0)) { - char *pszComment; - WORD wCommentLength; - - - wCommentLength = pTLV->wLen; - - pszComment = (char*)SAFE_MALLOC(wCommentLength + 1); - // Copy buffer to utf-8 buffer - memcpy(pszComment, pTLV->pData, wCommentLength); - pszComment[wCommentLength] = 0; // Terminate string - - debugLogA("Comment is '%s'", pszComment); - - // Write comment to database - if (getByte("LoadServerDetails", DEFAULT_SS_LOAD) || bAdded) { // if just added contact, save details always - does no harm - char *szOldComment; - - if (szOldComment = getSettingStringUtf(hContact, "UserInfo", "MyNotes", nullptr)) { - if ((mir_strcmp(szOldComment, pszComment)) && (mir_strlen(pszComment) > 0)) // check if the truncated comment changed, i.e. do not overwrite locally stored longer comment - if (mir_strlen(szOldComment) <= mir_strlen(pszComment) || strncmp((char*)szOldComment, (char*)pszComment, null_strcut(szOldComment, MAX_SSI_TLV_COMMENT_SIZE))) - db_set_utf(hContact, "UserInfo", "MyNotes", pszComment); - - SAFE_FREE((void**)&szOldComment); - } - else if (mir_strlen(pszComment) > 0) - db_set_utf(hContact, "UserInfo", "MyNotes", pszComment); - } - SAFE_FREE((void**)&pszComment); - } - else debugLogA("Invalid comment"); - } - - // Look for need-authorization TLV - if (pChain->getTLV(SSI_TLV_AWAITING_AUTH, 1)) { - setByte(hContact, "Auth", 1); - debugLogA("SSI contact need authorization"); - } - else setByte(hContact, "Auth", 0); - - if (pTLV = pChain->getTLV(SSI_TLV_METAINFO_TOKEN, 1)) { - setSettingBlob(hContact, DBSETTING_METAINFO_TOKEN, pTLV->pData, pTLV->wLen); - if (pChain->getTLV(SSI_TLV_METAINFO_TIME, 1)) - setSettingDouble(hContact, DBSETTING_METAINFO_TIME, pChain->getDouble(SSI_TLV_METAINFO_TIME, 1)); - debugLogA("SSI contact has meta info token"); - } - else { - delSetting(hContact, DBSETTING_METAINFO_TOKEN); - delSetting(hContact, DBSETTING_METAINFO_TIME); - } - - { // store server-list item's TLV data - BYTE* data = (BYTE*)SAFE_MALLOC(wTlvLength); - int datalen = getServerDataFromItemTLV(pChain, data); - - if (datalen > 0) - setSettingBlob(hContact, DBSETTING_SERVLIST_DATA, data, datalen); - else - delSetting(hContact, DBSETTING_SERVLIST_DATA); - - SAFE_FREE((void**)&data); - } - } - } - else // failed to add or other error - debugLogA("SSI failed to handle %s Item '%s'", "Buddy", szRecordName); - } - break; - - case SSI_ITEM_GROUP: - if ((wGroupId == 0) && (wItemId == 0)) { - /* list of groups. wTlvType=1, data is TLV(C8) containing list of WORDs which */ - /* is the group ids - /* we don't need to use this. Our processing is on-the-fly */ - /* this record is always sent first in the first packet only, */ - } - else if (wGroupId != 0) { - /* wGroupId != 0: a group record */ - if (wItemId == 0) { /* no item ID: this is a group */ - /* pszRecordName is the name of the group */ - ReserveServerID(wGroupId, SSIT_GROUP, 0); - - setServListGroupName(wGroupId, szRecordName); - - debugLogA("Group %s added to known groups.", szRecordName); - - /* demangle full grouppath, set it to known */ - SAFE_FREE(&szActiveSrvGroup); - szActiveSrvGroup = getServListGroupCListPath(wGroupId); - wActiveSrvGroupId = wGroupId; - - /* TLV contains a TLV(C8) with a list of WORDs of contained contact IDs */ - /* our processing is good enough that we don't need this duplication */ - } - else debugLogA("Unhandled type 0x01, wItemID != 0"); - } - else debugLogA("Unhandled type 0x01"); - break; - - case SSI_ITEM_PERMIT: - { - /* item on visible list */ - /* wItemId not related to contact ID */ - /* pszRecordName is the UIN */ - int bAdded; - MCONTACT hContact = HContactFromRecordName(szRecordName, &bAdded); - - if (hContact != INVALID_CONTACT_ID) { - if (bAdded) { - debugLogA("SSI added new %s contact '%s'", "Permit", szRecordName); - // It wasn't previously in the list, we hide it so it only appears in the visible list - setContactHidden(hContact, 1); - // Add it to the list, so it can be added properly if proper contact - AddJustAddedContact(hContact); - } - else debugLogA("SSI %s contact already exists '%s'", "Permit", szRecordName); - - // Save permit ID - setWord(hContact, DBSETTING_SERVLIST_PERMIT, wItemId); - ReserveServerID(wItemId, SSIT_ITEM, 0); - // Set apparent mode - setWord(hContact, "ApparentMode", ID_STATUS_ONLINE); - debugLogA("Visible-contact (%s)", szRecordName); - } - else { // failed to add or other error - debugLogA("SSI failed to handle %s Item '%s'", "Permit", szRecordName); - ReserveServerID(wItemId, SSIT_ITEM, SSIF_UNHANDLED); - } - } - break; - - case SSI_ITEM_DENY: - { - /* Item on invisible list */ - /* wItemId not related to contact ID */ - /* pszRecordName is the UIN */ - int bAdded; - MCONTACT hContact = HContactFromRecordName(szRecordName, &bAdded); - - if (hContact != INVALID_CONTACT_ID) { - if (bAdded) { - /* not already on list: added */ - debugLogA("SSI added new %s contact '%s'", "Deny", szRecordName); - // It wasn't previously in the list, we hide it so it only appears in the visible list - setContactHidden(hContact, 1); - // Add it to the list, so it can be added properly if proper contact - AddJustAddedContact(hContact); - } - else debugLogA("SSI %s contact already exists '%s'", "Deny", szRecordName); - - // Save Deny ID - setWord(hContact, DBSETTING_SERVLIST_DENY, wItemId); - ReserveServerID(wItemId, SSIT_ITEM, 0); - - // Set apparent mode - setWord(hContact, "ApparentMode", ID_STATUS_OFFLINE); - debugLogA("Invisible-contact (%s)", szRecordName); - } - else { // failed to add or other error - debugLogA("SSI failed to handle %s Item '%s'", "Deny", szRecordName); - ReserveServerID(wItemId, SSIT_ITEM, SSIF_UNHANDLED); - } - } - break; - - case SSI_ITEM_VISIBILITY: /* My visibility settings */ - // Look for visibility TLV - if (BYTE bVisibility = pChain->getByte(SSI_TLV_VISIBILITY, 1)) { // found it, store the id, we do not need current visibility - we do not rely on it - setWord(DBSETTING_SERVLIST_PRIVACY, wItemId); - ReserveServerID(wItemId, SSIT_ITEM, 0); - - debugLogA("Visibility is %u", bVisibility); - } - else ReserveServerID(wItemId, SSIT_ITEM, SSIF_UNHANDLED); - break; - - case SSI_ITEM_IGNORE: - { - /* item on ignore list */ - /* wItemId not related to contact ID */ - /* pszRecordName is the UIN */ - int bAdded; - MCONTACT hContact = HContactFromRecordName(szRecordName, &bAdded); - - if (hContact != INVALID_CONTACT_ID) { - if (bAdded) { - /* not already on list: add */ - debugLogA("SSI added new %s contact '%s'", "Ignore", szRecordName); - // It wasn't previously in the list, we hide it - setContactHidden(hContact, 1); - // Add it to the list, so it can be added properly if proper contact - AddJustAddedContact(hContact); - } - else debugLogA("SSI %s contact already exists '%s'", "Ignore", szRecordName); - - // Save Ignore ID - setWord(hContact, DBSETTING_SERVLIST_IGNORE, wItemId); - ReserveServerID(wItemId, SSIT_ITEM, 0); - - // Set apparent mode & ignore - setWord(hContact, "ApparentMode", ID_STATUS_OFFLINE); - // set ignore all events - CallService(MS_IGNORE_IGNORE, hContact, IGNOREEVENT_ALL); - debugLogA("Ignore-contact (%s)", szRecordName); - } - else { // failed to add or other error - debugLogA("SSI failed to handle %s Item '%s'", "Ignore", szRecordName); - ReserveServerID(wItemId, SSIT_ITEM, SSIF_UNHANDLED); - } - } - break; - - case SSI_ITEM_UNKNOWN2: - debugLogA("SSI unknown type 0x11"); - - ReserveServerID(wItemId, SSIT_ITEM, SSIF_UNHANDLED); - break; - - case SSI_ITEM_IMPORTTIME: - if (wGroupId == 0) { - /* time our list was first imported */ - /* pszRecordName is "Import Time" */ - /* data is TLV(13) {TLV(D4) {time_t importTime}} */ - setDword("ImportTS", pChain->getDWord(SSI_TLV_TIMESTAMP, 1)); - setWord("SrvImportID", wItemId); - ReserveServerID(wItemId, SSIT_ITEM, 0); - debugLogA("SSI %s item recognized", "first import"); - } - break; - - case SSI_ITEM_BUDDYICON: - if (wGroupId == 0) { - /* our avatar MD5-hash */ - /* pszRecordName is "1" */ - /* data is TLV(D5) hash */ - /* we ignore this, just save the id */ - /* cause we get the hash again after login */ - if (!mir_strcmp(szRecordName, "12")) { // need to handle Photo Item separately - setWord(DBSETTING_SERVLIST_PHOTO, wItemId); - debugLogA("SSI %s item recognized", "Photo"); - } - else { - setWord(DBSETTING_SERVLIST_AVATAR, wItemId); - debugLogA("SSI %s item recognized", "Avatar"); - } - ReserveServerID(wItemId, SSIT_ITEM, 0); - } - break; - - case SSI_ITEM_METAINFO: - if (wGroupId == 0) { - /* our meta info token & last update time */ - /* pszRecordName is "ICQ-MDIR" */ - /* data is TLV(15C) and TLV(15D) */ - oscar_tlv* pToken = pChain->getTLV(SSI_TLV_METAINFO_TOKEN, 1); - oscar_tlv* pTime = pChain->getTLV(SSI_TLV_METAINFO_TIME, 1); - if (pToken) - setSettingBlob(NULL, DBSETTING_METAINFO_TOKEN, pToken->pData, pToken->wLen); - if (pTime) - setSettingDouble(NULL, DBSETTING_METAINFO_TIME, pChain->getDouble(SSI_TLV_METAINFO_TIME, 1)); - - setWord(DBSETTING_SERVLIST_METAINFO, wItemId); - ReserveServerID(wItemId, SSIT_ITEM, 0); - - debugLogA("SSI %s item recognized", "Meta info"); - } - break; - - case SSI_ITEM_CLIENTDATA: - if (wGroupId == 0) { - /* ICQ2k ShortcutBar Items */ - /* data is TLV(CD) text */ - if (wItemId) - ReserveServerID(wItemId, SSIT_ITEM, SSIF_UNHANDLED); - } - - case SSI_ITEM_SAVED: - case SSI_ITEM_PREAUTH: - break; - - default: - debugLogA("SSI unhandled item %2x", wTlvType); - - if (wItemId) - ReserveServerID(wItemId, SSIT_ITEM, SSIF_UNHANDLED); - break; - } - - disposeChain(&pChain); - } // end for - - // Release Memory - SAFE_FREE(&szActiveSrvGroup); - - debugLogA("Bytes left: %u", wLen); - - setWord("SrvRecordCount", (WORD)(wRecord + getWord("SrvRecordCount", 0))); - - if (bIsLastPacket) { - // No contacts left to sync - bIsSyncingCL = FALSE; - - StoreServerIDs(); - - icq_RescanInfoUpdate(); - - if (wLen >= 4) { - DWORD dwLastUpdateTime; - - /* finally we get a time_t of the last update time */ - unpackDWord(&buf, &dwLastUpdateTime); - setDword("SrvLastUpdate", dwLastUpdateTime); - debugLogA("Last update of server list was (%u) %s", dwLastUpdateTime, time2text(dwLastUpdateTime)); - - sendRosterAck(); - handleServUINSettings(wListenPort, info); - - servlistProcessLogin(); - } - else debugLogA("Last packet missed update time..."); - - if (getWord("SrvRecordCount", 0) == 0) { // we got empty serv-list, create master group - cookie_servlist_action* ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action)); - if (ack) { - DWORD dwCookie; - - ack->dwAction = SSA_GROUP_UPDATE; - ack->szGroupName = null_strdup(""); - dwCookie = AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_ADDTOLIST, 0, ack); - icq_sendServerGroup(dwCookie, ICQ_LISTS_ADDTOLIST, 0, ack->szGroupName, nullptr, 0, 0); - } - } - // serv-list sync finished, clear just added contacts - FlushJustAddedContacts(); - } - else debugLogA("Waiting for more packets"); -} - -void CIcqProto::handleServerCListItemAdd(WORD wItemId, WORD wItemType, oscar_tlv_chain *pItemData) -{ - if (wItemType == SSI_ITEM_IMPORTTIME) { - if (pItemData) { - setDword("ImportTS", pItemData->getDWord(SSI_TLV_TIMESTAMP, 1)); - setWord("SrvImportID", wItemId); - ReserveServerID(wItemId, SSIT_ITEM, 0); - - debugLogA("Server added Import timestamp to list"); - return; - } - } - // Reserve server-list ID - ReserveServerID(wItemId, wItemType == SSI_ITEM_GROUP ? SSIT_GROUP : SSIT_ITEM, SSIF_UNHANDLED); -} - -void CIcqProto::handleServerCListItemUpdate(const char *szRecordName, WORD wItemType, oscar_tlv_chain *pItemData) -{ - MCONTACT hContact = (wItemType == SSI_ITEM_BUDDY || wItemType == SSI_ITEM_DENY || wItemType == SSI_ITEM_PERMIT || wItemType == SSI_ITEM_IGNORE) ? HContactFromRecordName(szRecordName, nullptr) : NULL; - - if (hContact != INVALID_CONTACT_ID && wItemType == SSI_ITEM_BUDDY) { // a contact was updated on server - if (pItemData) { - oscar_tlv *pAuth = pItemData->getTLV(SSI_TLV_AWAITING_AUTH, 1); - BYTE bAuth = getByte(hContact, "Auth", 0); - - if (bAuth && !pAuth) { // server authorized our contact - char str[MAX_PATH]; - char msg[MAX_PATH]; - char *nick = NickFromHandleUtf(hContact); - - setByte(hContact, "Auth", 0); - mir_snprintf(str, ICQTranslateUtfStatic(LPGEN("Contact \"%s\" was authorized in the server list."), msg, _countof(msg)), nick); - icq_LogMessage(LOG_WARNING, str); - SAFE_FREE(&nick); - } - else if (!bAuth && pAuth) { // server took away authorization of our contact - char str[MAX_PATH]; - char msg[MAX_PATH]; - char *nick = NickFromHandleUtf(hContact); - - setByte(hContact, "Auth", 1); - mir_snprintf(str, ICQTranslateUtfStatic(LPGEN("Contact \"%s\" lost its authorization in the server list."), msg, _countof(msg)), nick); - icq_LogMessage(LOG_WARNING, str); - SAFE_FREE(&nick); - } - { - // update metainfo data - DBVARIANT dbv = { 0 }; - oscar_tlv *pToken = pItemData->getTLV(SSI_TLV_METAINFO_TOKEN, 1); - oscar_tlv *pTime = pItemData->getTLV(SSI_TLV_METAINFO_TIME, 1); - - if (!getSetting(hContact, DBSETTING_METAINFO_TOKEN, &dbv)) { - if (!pToken || dbv.cpbVal != pToken->wLen || memcmp(dbv.pbVal, pToken->pData, dbv.cpbVal)) { - if (!pToken) - debugLogA("Contact %s, meta info token removed", szRecordName); - else - debugLogA("Contact %s, meta info token changed", szRecordName); - - // user info was changed, refresh - if (IsMetaInfoChanged(hContact)) - icq_QueueUser(hContact); - } - - db_free(&dbv); - } - else if (pToken) { - debugLogA("Contact %s, meta info token added", szRecordName); - - // user info was changed, refresh - if (IsMetaInfoChanged(hContact)) - icq_QueueUser(hContact); - } - - if (pToken) - setSettingBlob(hContact, DBSETTING_METAINFO_TOKEN, pToken->pData, pToken->wLen); - if (pTime) - setSettingDouble(hContact, DBSETTING_METAINFO_TIME, pItemData->getDouble(SSI_TLV_METAINFO_TIME, 1)); - } - { - // update server's data - otherwise consequent operations can fail with 0x0E - BYTE *data = (BYTE*)_alloca(pItemData->getChainLength()); - int datalen = getServerDataFromItemTLV(pItemData, data); - - if (datalen > 0) - setSettingBlob(hContact, DBSETTING_SERVLIST_DATA, data, datalen); - else - delSetting(hContact, DBSETTING_SERVLIST_DATA); - } - } - } - else if (wItemType == SSI_ITEM_METAINFO) { // owner MetaInfo data updated - if (pItemData) { - DBVARIANT dbv = { 0 }; - oscar_tlv *pToken = pItemData->getTLV(SSI_TLV_METAINFO_TOKEN, 1); - oscar_tlv *pTime = pItemData->getTLV(SSI_TLV_METAINFO_TIME, 1); - - if (!getSetting(hContact, DBSETTING_METAINFO_TOKEN, &dbv)) { - if (!pToken || dbv.cpbVal != pToken->wLen || memcmp(dbv.pbVal, pToken->pData, dbv.cpbVal)) { - if (!pToken) - debugLogA("Owner meta info token removed"); - else - debugLogA("Owner meta info token changed"); - } - - db_free(&dbv); - } - - if (pToken) - setSettingBlob(hContact, DBSETTING_METAINFO_TOKEN, pToken->pData, pToken->wLen); - if (pTime) - setSettingDouble(hContact, DBSETTING_METAINFO_TIME, pItemData->getDouble(SSI_TLV_METAINFO_TIME, 1)); - } - } - else if (wItemType == SSI_ITEM_GROUP) // group updated - debugLogA("Server updated our group \"%s\" on list", szRecordName); -} - -void CIcqProto::handleServerCListItemDelete(const char *szRecordName, WORD wItemId, WORD wItemType) -{ - MCONTACT hContact = (wItemType == SSI_ITEM_BUDDY || wItemType == SSI_ITEM_DENY || wItemType == SSI_ITEM_PERMIT || wItemType == SSI_ITEM_IGNORE) ? HContactFromRecordName(szRecordName, nullptr) : NULL; - - if (hContact != INVALID_CONTACT_ID && wItemType == SSI_ITEM_BUDDY) { // a contact was removed from our list - if (getWord(hContact, DBSETTING_SERVLIST_ID, 0) == wItemId) { - delSetting(hContact, DBSETTING_SERVLIST_ID); - delSetting(hContact, DBSETTING_SERVLIST_GROUP); - delSetting(hContact, "Auth"); - - char str[MAX_PATH]; - char msg[MAX_PATH]; - char *nick = NickFromHandleUtf(hContact); - - mir_snprintf(str, ICQTranslateUtfStatic(LPGEN("User \"%s\" was removed from server list."), msg, _countof(msg)), nick); - icq_LogMessage(LOG_WARNING, str); - SAFE_FREE(&nick); - } - } - // Release server-list ID - FreeServerID(wItemId, wItemType == SSI_ITEM_GROUP ? SSIT_GROUP : SSIT_ITEM); -} - -void CIcqProto::handleRecvAuthRequest(BYTE *buf, size_t wLen) -{ - DWORD dwUin; - uid_str szUid; - if (!unpackUID(&buf, &wLen, &dwUin, &szUid)) - return; - - if (dwUin && IsOnSpammerList(dwUin)) { - debugLogA("Ignored Message from known Spammer"); - return; - } - - WORD wReasonLen; - unpackWord(&buf, &wReasonLen); - wLen -= 2; - if (wReasonLen > wLen) - return; - - int bAdded; - MCONTACT hContact = HContactFromUID(dwUin, szUid, &bAdded); - - // Prepare reason - char *szReason = (char*)SAFE_MALLOC(wReasonLen + 1); - if (szReason) { - memcpy(szReason, buf, wReasonLen); - szReason[wReasonLen] = '\0'; - } - - // Read nick name from DB - char *szNick; - if (dwUin) - szNick = getSettingStringUtf(hContact, "Nick", nullptr); - else - szNick = null_strdup(szUid); - - DB_AUTH_BLOB blob(hContact, szNick, nullptr, nullptr, nullptr, szReason); - blob.set_uin(dwUin); - - setByte(hContact, "Grant", 1); - - // TODO: Change for new auth system, include all known informations - PROTORECVEVENT pre = { 0 }; - pre.timestamp = time(0); - pre.lParam = blob.size(); - pre.szMessage = blob; - ProtoChainRecv(hContact, PSR_AUTH, 0, (LPARAM)&pre); - - SAFE_FREE(&szNick); - SAFE_FREE(&szReason); -} - -void CIcqProto::handleRecvAdded(BYTE *buf, size_t wLen) -{ - PBYTE pBlob, pCurBlob; - DBVARIANT dbv = { 0 }; - - DWORD dwUin; - uid_str szUid; - if (!unpackUID(&buf, &wLen, &dwUin, &szUid)) - return; - - if (dwUin && IsOnSpammerList(dwUin)) { - debugLogA("Ignored Message from known Spammer"); - return; - } - - int bAdded; - MCONTACT hContact = HContactFromUID(dwUin, szUid, &bAdded); - - size_t nNickLen, cbBlob = sizeof(DWORD) * 2 + 4; - - char *szNick = nullptr; - if (dwUin) { - if (getString(hContact, "Nick", &dbv)) - nNickLen = 0; - else { - szNick = dbv.pszVal; - nNickLen = mir_strlen(szNick); - } - } - else nNickLen = mir_strlen(szUid); - - cbBlob += nNickLen; - - pCurBlob = pBlob = (PBYTE)_alloca(cbBlob); - /*blob is: uin(DWORD), hContact(HANDLE), nick(ASCIIZ), first(ASCIIZ), last(ASCIIZ), email(ASCIIZ) */ - *(DWORD*)pCurBlob = dwUin; pCurBlob += sizeof(DWORD); - *(DWORD*)pCurBlob = hContact; pCurBlob += sizeof(DWORD); - if (nNickLen && dwUin) { // if we have nick we add it, otherwise keep trailing zero - memcpy(pCurBlob, szNick, nNickLen); - pCurBlob += nNickLen; - } - else { - memcpy(pCurBlob, szUid, nNickLen); - pCurBlob += nNickLen; - } - *(char*)pCurBlob = 0; pCurBlob++; - *(char*)pCurBlob = 0; pCurBlob++; - *(char*)pCurBlob = 0; pCurBlob++; - *(char*)pCurBlob = 0; - // TODO: Change for new auth system - - AddEvent(NULL, EVENTTYPE_ADDED, time(0), 0, cbBlob, pBlob); -} - -void CIcqProto::handleRecvAuthResponse(BYTE *buf, size_t wLen) -{ - DWORD dwUin; - uid_str szUid; - char* szNick = nullptr; - WORD nReasonLen; - char* szReason; - int bAdded; - - BYTE bResponse = 0xFF; - - if (!unpackUID(&buf, &wLen, &dwUin, &szUid)) return; - - if (dwUin && IsOnSpammerList(dwUin)) { - debugLogA("Ignored Message from known Spammer"); - return; - } - - MCONTACT hContact = HContactFromUID(dwUin, szUid, &bAdded); - if (hContact != INVALID_CONTACT_ID) - szNick = NickFromHandle(hContact); - - if (wLen > 0) { - unpackByte(&buf, &bResponse); - wLen -= 1; - } - if (wLen >= 2) { - unpackWord(&buf, &nReasonLen); - wLen -= 2; - if (wLen >= nReasonLen) { - szReason = (char*)_alloca(nReasonLen + 1); - unpackString(&buf, szReason, nReasonLen); - szReason[nReasonLen] = '\0'; - } - } - - switch (bResponse) { - case 0: - debugLogA("Authorization request %s by %s", "denied", strUID(dwUin, szUid)); - // TODO: Add to system history as soon as new auth system is ready - break; - - case 1: - setByte(hContact, "Auth", 0); - debugLogA("Authorization request %s by %s", "granted", strUID(dwUin, szUid)); - // TODO: Add to system history as soon as new auth system is ready - break; - - default: - debugLogA("Unknown Authorization request response (%u) from %s", bResponse, strUID(dwUin, szUid)); - break; - - } - SAFE_FREE(&szNick); -} - -// Updates the visibility code used while in SSI mode. If a server ID is -// not stored in the local DB, a new ID will be added to the server list. -// -// Possible values are: -// 01 - Allow all users to see you -// 02 - Block all users from seeing you -// 03 - Allow only users in the permit list to see you -// 04 - Block only users in the invisible list from seeing you -// 05 - Allow only users in the buddy list to see you -// -void CIcqProto::updateServVisibilityCode(BYTE bCode) -{ - icq_packet packet; - WORD wVisibilityID; - WORD wCommand; - - if ((bCode > 0) && (bCode < 6)) { - cookie_servlist_action* ack; - DWORD dwCookie; - BYTE bVisibility = getByte("SrvVisibility", 0); - - if (bVisibility == bCode) // if no change was made, not necescary to update that - return; - setByte("SrvVisibility", bCode); - - // Do we have a known server visibility ID? We should, unless we just subscribed to the serv-list for the first time - if ((wVisibilityID = getWord(DBSETTING_SERVLIST_PRIVACY, 0)) == 0) { - // No, create a new random ID - wVisibilityID = GenerateServerID(SSIT_ITEM, 0); - setWord(DBSETTING_SERVLIST_PRIVACY, wVisibilityID); - wCommand = ICQ_LISTS_ADDTOLIST; - - debugLogA("Made new srvVisibilityID, id is %u, code is %u", wVisibilityID, bCode); - } - else { - debugLogA("Reused srvVisibilityID, id is %u, code is %u", wVisibilityID, bCode); - wCommand = ICQ_LISTS_UPDATEGROUP; - } - - ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action)); - if (!ack) { - debugLogA("Cookie alloc failure."); - return; // out of memory, go away - } - - ack->dwAction = SSA_VISIBILITY; // update visibility - dwCookie = AllocateCookie(CKT_SERVERLIST, wCommand, 0, ack); // take cookie - - // Build and send packet - serverPacketInit(&packet, 25); - packFNACHeader(&packet, ICQ_LISTS_FAMILY, wCommand, 0, dwCookie); - packWord(&packet, 0); // Name (null) - packWord(&packet, 0); // GroupID (0 if not relevant) - packWord(&packet, wVisibilityID); // EntryID - packWord(&packet, SSI_ITEM_VISIBILITY); // EntryType - packWord(&packet, 5); // Length in bytes of following TLV - packTLV(&packet, SSI_TLV_VISIBILITY, 1, &bCode); // TLV (Visibility) - sendServPacket(&packet); - // There is no need to send ICQ_LISTS_CLI_MODIFYSTART or - // ICQ_LISTS_CLI_MODIFYEND when modifying the visibility code - } -} - -// Updates the avatar hash used while in SSI mode. If a server ID is -// not stored in the local DB, a new ID will be added to the server list. -void CIcqProto::updateServAvatarHash(BYTE *pHash, int size) -{ - void** pDoubleObject = nullptr; - void* doubleObject = nullptr; - DWORD dwOperationFlags = 0; - WORD wAvatarID; - WORD wCommand; - char szItemName[2] = { 0, 0 }; - int bResetHash = 0; - DBVARIANT dbvHash; - - if (!pHash) - return; - - if (!getSetting(NULL, "AvatarHash", &dbvHash)) { - szItemName[0] = 0x30 + dbvHash.pbVal[1]; - - if (memcmp(pHash, dbvHash.pbVal, 2) != 0) // add code to remove old hash from server - bResetHash = 1; - - db_free(&dbvHash); - } - - if (bResetHash) { // start update session - // pair the packets (need to be send in the correct order - dwOperationFlags |= SSOF_BEGIN_OPERATION | SSOF_END_OPERATION; - pDoubleObject = &doubleObject; - } - - if (bResetHash) { - // Do we have a known server avatar ID? - if (wAvatarID = getWord(DBSETTING_SERVLIST_AVATAR, 0)) { - cookie_servlist_action *ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action)); - if (!ack) { - debugLogA("Cookie alloc failure."); - return; // out of memory, go away - } - ack->dwAction = SSA_REMOVEAVATAR; // update avatar hash - ack->wContactId = wAvatarID; - DWORD dwCookie = AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_REMOVEFROMLIST, 0, ack); // take cookie - icq_sendServerItem(dwCookie, ICQ_LISTS_REMOVEFROMLIST, 0, wAvatarID, szItemName, nullptr, 0, SSI_ITEM_BUDDYICON, SSOP_ITEM_ACTION | dwOperationFlags, 400, pDoubleObject); - } - } - - WORD hashsize = size - 2; - - // Do we have a known server avatar ID? We should, unless we just subscribed to the serv-list for the first time - if (bResetHash || (wAvatarID = getWord(DBSETTING_SERVLIST_AVATAR, 0)) == 0) { - // No, create a new random ID - wAvatarID = GenerateServerID(SSIT_ITEM, 0); - wCommand = ICQ_LISTS_ADDTOLIST; - debugLogA("Made new srvAvatarID, id is %u", wAvatarID); - } - else { - debugLogA("Reused srvAvatarID, id is %u", wAvatarID); - wCommand = ICQ_LISTS_UPDATEGROUP; - } - - cookie_servlist_action *ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action)); - if (!ack) { - debugLogA("Cookie alloc failure."); - return; // out of memory, go away - } - ack->dwAction = SSA_SETAVATAR; // update avatar hash - ack->wContactId = wAvatarID; - DWORD dwCookie = AllocateCookie(CKT_SERVERLIST, wCommand, 0, ack); // take cookie - - szItemName[0] = 0x30 + pHash[1]; - - // Build the packet - WORD wTLVlen = 8 + hashsize; - - // Initialize our handy data buffer - icq_packet pBuffer; - pBuffer.wPlace = 0; - pBuffer.pData = (BYTE *)_alloca(wTLVlen); - pBuffer.wLen = wTLVlen; - - packTLV(&pBuffer, SSI_TLV_NAME, 0, nullptr); // TLV (Name) - packTLV(&pBuffer, SSI_TLV_AVATARHASH, hashsize, pHash + 2); // TLV (Hash) - - icq_sendServerItem(dwCookie, wCommand, 0, wAvatarID, szItemName, pBuffer.pData, wTLVlen, SSI_ITEM_BUDDYICON, SSOP_ITEM_ACTION | dwOperationFlags, 400, pDoubleObject); - // There is no need to send ICQ_LISTS_CLI_MODIFYSTART or - // ICQ_LISTS_CLI_MODIFYEND when modifying the avatar hash -} - -// Should be called before the server list is modified. When all -// modifications are done, call icq_sendServerEndOperation(). -// Called automatically thru server-list update board! -void CIcqProto::icq_sendServerBeginOperation(int bImport) -{ - WORD wImportID = getWord("SrvImportID", 0); - - if (bImport && wImportID) { // we should be importing, check if already have import item - if (getDword("ImportTS", 0) + 604800 < getDword("LogonTS", 0)) { // is the timestamp week older, clear it and begin new import - DWORD dwCookie; - cookie_servlist_action* ack; - - if (ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action))) { // we have cookie good, go on - ack->dwAction = SSA_IMPORT; - dwCookie = AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_REMOVEFROMLIST, 0, ack); - - icq_sendSimpleItem(dwCookie, ICQ_LISTS_REMOVEFROMLIST, 0, "ImportTime", 0, wImportID, SSI_ITEM_IMPORTTIME, SSOP_ITEM_ACTION | SSOF_SEND_DIRECTLY, 100); - } - } - } - - icq_packet packet; - serverPacketInit(&packet, bImport ? 14 : 10); - packFNACHeader(&packet, ICQ_LISTS_FAMILY, ICQ_LISTS_CLI_MODIFYSTART); - if (bImport) - packDWord(&packet, 1 << 0x10); - sendServPacket(&packet); -} - -// Should be called after the server list has been modified to inform -// the server that we are done. -// Called automatically thru server-list update board! -void CIcqProto::icq_sendServerEndOperation() -{ - icq_packet packet; - serverPacketInit(&packet, 10); - packFNACHeader(&packet, ICQ_LISTS_FAMILY, ICQ_LISTS_CLI_MODIFYEND); - sendServPacket(&packet); -} - -// Sent when the last roster packet has been received -void CIcqProto::sendRosterAck(void) -{ - icq_packet packet; - serverPacketInit(&packet, 10); - packFNACHeader(&packet, ICQ_LISTS_FAMILY, ICQ_LISTS_GOTLIST); - sendServPacket(&packet); - - debugLogA("Sent SNAC(x13,x07) - CLI_ROSTERACK"); -} diff --git a/protocols/IcqOscarJ/src/fam_15icqserver.cpp b/protocols/IcqOscarJ/src/fam_15icqserver.cpp deleted file mode 100644 index db4509ec21..0000000000 --- a/protocols/IcqOscarJ/src/fam_15icqserver.cpp +++ /dev/null @@ -1,1068 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -void CIcqProto::handleIcqExtensionsFam(BYTE *pBuffer, size_t wBufferLength, snac_header* pSnacHeader) -{ - switch (pSnacHeader->wSubtype) { - case ICQ_META_ERROR: - handleExtensionError(pBuffer, wBufferLength); - break; - - case ICQ_META_SRV_REPLY: - handleExtensionServerInfo(pBuffer, wBufferLength, pSnacHeader->wFlags); - break; - - default: - debugLogA("Warning: Ignoring SNAC(x%02x,x%02x) - Unknown SNAC (Flags: %u, Ref: %u)", ICQ_EXTENSIONS_FAMILY, pSnacHeader->wSubtype, pSnacHeader->wFlags, pSnacHeader->dwRef); - break; - } -} - - -void CIcqProto::handleExtensionError(BYTE *buf, size_t wPackLen) -{ - WORD wErrorCode; - - if (wPackLen < 2) - wErrorCode = 0; - - if (wPackLen >= 2 && wPackLen <= 6) - unpackWord(&buf, &wErrorCode); - else { - // TODO: cookies need to be handled and freed here on error - unpackWord(&buf, &wErrorCode); - wPackLen -= 2; - - oscar_tlv_chain *chain = readIntoTLVChain(&buf, wPackLen, 0); - if (chain) { - oscar_tlv* pTLV; - - pTLV = chain->getTLV(0x21, 1); // get meta error data - if (pTLV && pTLV->wLen >= 8) { - BYTE *pBuffer = pTLV->pData; - WORD wData; - pBuffer += 6; - unpackLEWord(&pBuffer, &wData); // get request type - switch (wData) { - case CLI_META_INFO_REQ: - if (pTLV->wLen >= 12) { - WORD wSubType; - WORD wCookie; - - unpackWord(&pBuffer, &wCookie); - unpackLEWord(&pBuffer, &wSubType); - // more sofisticated detection, send ack - if (wSubType == META_REQUEST_FULL_INFO) { - MCONTACT hContact; - cookie_fam15_data *pCookieData = nullptr; - - int foundCookie = FindCookie(wCookie, &hContact, (void**)&pCookieData); - if (foundCookie && pCookieData) { - ProtoBroadcastAck(hContact, ACKTYPE_GETINFO, ACKRESULT_FAILED, (HANDLE)1, 0); - - ReleaseCookie(wCookie); // we do not leak cookie and memory - } - - debugLogA("Full info request error 0x%02x received", wErrorCode); - } - else if (wSubType == META_SET_PASSWORD_REQ) { - // failed to change user password, report to UI - ProtoBroadcastAck(NULL, ACKTYPE_SETINFO, ACKRESULT_FAILED, (HANDLE)wCookie, 0); - - debugLogA("Meta change password request failed, error 0x%02x", wErrorCode); - } - else debugLogA("Meta request error 0x%02x received", wErrorCode); - } - else debugLogA("Meta request error 0x%02x received", wErrorCode); - break; - - default: - debugLogA("Unknown request 0x%02x error 0x%02x received", wData, wErrorCode); - } - disposeChain(&chain); - return; - } - disposeChain(&chain); - } - } - LogFamilyError(ICQ_EXTENSIONS_FAMILY, wErrorCode); -} - -void CIcqProto::handleExtensionServerInfo(BYTE *buf, size_t wPackLen, WORD wFlags) -{ - // The entire packet is encapsulated in a TLV type 1 - oscar_tlv_chain *chain = readIntoTLVChain(&buf, wPackLen, 0); - if (chain == nullptr) { - debugLogA("Error: Broken snac 15/3 %d", 1); - return; - } - - oscar_tlv *dataTlv = chain->getTLV(0x0001, 1); - if (dataTlv == nullptr) { - disposeChain(&chain); - debugLogA("Error: Broken snac 15/3 %d", 2); - return; - } - - BYTE *databuf = dataTlv->pData; - wPackLen -= 4; - - _ASSERTE(dataTlv->wLen == wPackLen); - _ASSERTE(wPackLen >= 10); - - if ((dataTlv->wLen == wPackLen) && (wPackLen >= 10)) { - DWORD dwMyUin; - WORD wBytesRemaining, wCookie, wRequestType; - unpackLEWord(&databuf, &wBytesRemaining); - unpackLEDWord(&databuf, &dwMyUin); - unpackLEWord(&databuf, &wRequestType); - unpackWord(&databuf, &wCookie); - - _ASSERTE(wBytesRemaining == (wPackLen - 2)); - if (wBytesRemaining == (wPackLen - 2)) { - wPackLen -= 10; - switch (wRequestType) { - case SRV_META_INFO_REPLY: // SRV_META request replies - handleExtensionMetaResponse(databuf, wPackLen, wCookie, wFlags); - break; - - default: - debugLogA("Warning: Ignoring Meta response - Unknown type %d", wRequestType); - break; - } - } - } - else debugLogA("Error: Broken snac 15/3 %d", 3); - - if (chain) - disposeChain(&chain); -} - - -void CIcqProto::handleExtensionMetaResponse(BYTE *databuf, size_t wPacketLen, WORD wCookie, WORD wFlags) -{ - WORD wReplySubtype; - BYTE bResultCode; - - _ASSERTE(wPacketLen >= 3); - if (wPacketLen >= 3) { - // Reply subtype - unpackLEWord(&databuf, &wReplySubtype); - wPacketLen -= 2; - - // Success byte - unpackByte(&databuf, &bResultCode); - wPacketLen -= 1; - - switch (wReplySubtype) { - case META_SET_PASSWORD_ACK: - parseUserInfoUpdateAck(wCookie, wReplySubtype, bResultCode); - break; - - case SRV_RANDOM_FOUND: - case SRV_USER_FOUND: - case SRV_LAST_USER_FOUND: - parseSearchReplies(databuf, wPacketLen, wCookie, wReplySubtype, bResultCode); - break; - - case META_PROCESSING_ERROR: // Meta processing error server reply - // Todo: We only use this as an SMS ack, that will have to change - { - // Terminate buffer - char *pszInfo = (char *)_alloca(wPacketLen + 1); - if (wPacketLen > 0) - memcpy(pszInfo, databuf, wPacketLen); - pszInfo[wPacketLen] = 0; - - ProtoBroadcastAck(NULL, ICQACKTYPE_SMS, ACKRESULT_FAILED, (HANDLE)wCookie, (LPARAM)pszInfo); - FreeCookie(wCookie); - } - break; - - case META_SMS_DELIVERY_RECEIPT: - // Todo: This overlaps with META_SET_AFFINFO_ACK. - // Todo: Check what happens if result != A - if (wPacketLen > 8) { - databuf += 6; // Some unknowns - wPacketLen -= 6; - - size_t wNetworkNameLen, wAckLen; - unpackWord(&databuf, &wNetworkNameLen); - if (wPacketLen >= (wNetworkNameLen + 2)) { - databuf += wNetworkNameLen; - wPacketLen -= wNetworkNameLen; - - unpackWord(&databuf, &wAckLen); - char *pszInfo = (char*)_alloca(wAckLen + 1); - // Terminate buffer - if (wAckLen > 0) - memcpy(pszInfo, databuf, wAckLen); - pszInfo[wAckLen] = 0; - - ProtoBroadcastAck(NULL, ICQACKTYPE_SMS, ACKRESULT_SENTREQUEST, (HANDLE)wCookie, (LPARAM)pszInfo); - FreeCookie(wCookie); - - // Parsing success - break; - } - } - - // Parsing failure - debugLogA("Error: Failure parsing META_SMS_DELIVERY_RECEIPT"); - break; - - case META_DIRECTORY_DATA: - case META_DIRECTORY_RESPONSE: - if (bResultCode == 0x0A) - handleDirectoryQueryResponse(databuf, wPacketLen, wCookie, wReplySubtype, wFlags); - else - debugLogA("Error: Directory request failed, code %u", bResultCode); - break; - - case META_DIRECTORY_UPDATE_ACK: - if (bResultCode == 0x0A) - handleDirectoryUpdateResponse(databuf, wPacketLen, wCookie); - else - debugLogA("Error: Directory request failed, code %u", bResultCode); - break; - - case META_BASIC_USERINFO: - case META_WORK_USERINFO: - case META_MORE_USERINFO: - case META_NOTES_USERINFO: - case META_EMAIL_USERINFO: - case META_INTERESTS_USERINFO: - case META_AFFILATIONS_USERINFO: - case META_SHORT_USERINFO: - case META_HPAGECAT_USERINFO: - debugLogA("Warning: Ignored 15/03 (legacy user info) replysubtype x%x", wReplySubtype); - break; - - default: - debugLogA("Warning: Ignored 15/03 replysubtype x%x", wReplySubtype); - break; - } - - // Success - return; - } - - // Failure - debugLogA("Warning: Broken 15/03 ExtensionMetaResponse"); -} - -void CIcqProto::ReleaseSearchCookie(DWORD dwCookie, cookie_search *pCookie) -{ - if (pCookie) { - FreeCookie(dwCookie); - if (pCookie->dwMainId) { - if (pCookie->dwStatus) { - SAFE_FREE((void**)&pCookie); - ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)dwCookie, 0); - } - else pCookie->dwStatus = 1; - } - else { - SAFE_FREE((void**)&pCookie); - ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)dwCookie, 0); - } - } - else ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)dwCookie, 0); -} - -void CIcqProto::parseSearchReplies(unsigned char *databuf, size_t wPacketLen, WORD wCookie, WORD wReplySubtype, BYTE bResultCode) -{ - BYTE bParsingOK = FALSE; // For debugging purposes only - BOOL bLastUser = FALSE; - - cookie_search *pCookie; - if (!FindCookie(wCookie, nullptr, (void**)&pCookie)) { - debugLogA("Warning: Received unexpected search reply"); - pCookie = nullptr; - } - - switch (wReplySubtype) { - case SRV_LAST_USER_FOUND: // Search: last user found reply - bLastUser = TRUE; - - case SRV_USER_FOUND: // Search: user found reply - if (bLastUser) - debugLogA("SNAC(0x15,0x3): Last search reply"); - else - debugLogA("SNAC(0x15,0x3): Search reply"); - - if (bResultCode == 0xA) { - ICQSEARCHRESULT sr = { 0 }; - DWORD dwUin; - char szUin[UINMAXLEN]; - size_t wLen; - - sr.hdr.cbSize = sizeof(sr); - - // Remaining bytes - if (wPacketLen < 2) - break; - unpackLEWord(&databuf, &wLen); - wPacketLen -= 2; - - _ASSERTE(wLen <= wPacketLen); - if (wLen > wPacketLen) - break; - - // Uin - if (wPacketLen < 4) - break; - unpackLEDWord(&databuf, &dwUin); // Uin - wPacketLen -= 4; - sr.uin = dwUin; - _itoa(dwUin, szUin, 10); - sr.hdr.id.w = (wchar_t*)szUin; - - // Nick - if (wPacketLen < 2) - break; - unpackLEWord(&databuf, &wLen); - wPacketLen -= 2; - if (wLen > 0) { - if (wPacketLen < wLen || (databuf[wLen - 1] != 0)) - break; - sr.hdr.nick.w = (wchar_t*)databuf; - databuf += wLen; - } - else { - sr.hdr.nick.w = nullptr; - } - - // First name - if (wPacketLen < 2) - break; - unpackLEWord(&databuf, &wLen); - wPacketLen -= 2; - if (wLen > 0) { - if (wPacketLen < wLen || (databuf[wLen - 1] != 0)) - break; - sr.hdr.firstName.w = (wchar_t*)databuf; - databuf += wLen; - } - else sr.hdr.firstName.w = nullptr; - - // Last name - if (wPacketLen < 2) - break; - unpackLEWord(&databuf, &wLen); - wPacketLen -= 2; - if (wLen > 0) { - if (wPacketLen < wLen || (databuf[wLen - 1] != 0)) - break; - sr.hdr.lastName.w = (wchar_t*)databuf; - databuf += wLen; - } - else sr.hdr.lastName.w = nullptr; - - // E-mail name - if (wPacketLen < 2) - break; - unpackLEWord(&databuf, &wLen); - wPacketLen -= 2; - if (wLen > 0) { - if (wPacketLen < wLen || (databuf[wLen - 1] != 0)) - break; - sr.hdr.email.w = (wchar_t*)databuf; - databuf += wLen; - } - else sr.hdr.email.w = nullptr; - - // Authentication needed flag - if (wPacketLen < 1) - break; - unpackByte(&databuf, &sr.auth); - - // Finally, broadcast the result - ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)wCookie, (LPARAM)&sr); - - // Broadcast "Last result" ack if this was the last user found - if (wReplySubtype == SRV_LAST_USER_FOUND) { - if (wPacketLen >= 10) { - DWORD dwLeft; - - databuf += 5; - unpackLEDWord(&databuf, &dwLeft); - if (dwLeft) - debugLogA("Warning: %d search results omitted", dwLeft); - } - ReleaseSearchCookie(wCookie, pCookie); - } - bParsingOK = TRUE; - } - else { - // Failed search - debugLogA("SNAC(0x15,0x3): Search error %u", bResultCode); - - ReleaseSearchCookie(wCookie, pCookie); - - bParsingOK = TRUE; - } - break; - - case SRV_RANDOM_FOUND: // Random search server reply - default: - if (pCookie) - ReleaseCookie(wCookie); - break; - } - - // For debugging purposes only - if (!bParsingOK) { - debugLogA("Warning: Parsing error in 15/03 search reply type x%x", wReplySubtype); - _ASSERTE(!bParsingOK); - } -} - -void CIcqProto::parseUserInfoUpdateAck(WORD wCookie, WORD wReplySubtype, BYTE bResultCode) -{ - switch (wReplySubtype) { - case META_SET_PASSWORD_ACK: // Set user password server ack - if (bResultCode == 0xA) - ProtoBroadcastAck(NULL, ACKTYPE_SETINFO, ACKRESULT_SUCCESS, (HANDLE)wCookie, 0); - else - ProtoBroadcastAck(NULL, ACKTYPE_SETINFO, ACKRESULT_FAILED, (HANDLE)wCookie, 0); - - FreeCookie(wCookie); - break; - - default: - debugLogA("Warning: Ignored 15/03 user info update ack type x%x", wReplySubtype); - break; - } -} - -UserInfoRecordItem rEmail[] = -{ - { 0x64, DBVT_UTF8, "e-mail%u" } -}; - -UserInfoRecordItem rAddress[] = -{ - { 0x64, DBVT_UTF8, "Street" }, - { 0x6E, DBVT_UTF8, "City" }, - { 0x78, DBVT_UTF8, "State" }, - { 0x82, DBVT_UTF8, "ZIP" }, - { 0x8C, DBVT_WORD, "Country" } -}; - -UserInfoRecordItem rOriginAddress[] = -{ - { 0x64, DBVT_UTF8, "OriginStreet" }, - { 0x6E, DBVT_UTF8, "OriginCity" }, - { 0x78, DBVT_UTF8, "OriginState" }, - { 0x8C, DBVT_WORD, "OriginCountry" } -}; - -UserInfoRecordItem rCompany[] = -{ - { 0x64, DBVT_UTF8, "CompanyPosition" }, - { 0x6E, DBVT_UTF8, "Company" }, - { 0x7D, DBVT_UTF8, "CompanyDepartment" }, - { 0x78, DBVT_UTF8, "CompanyHomepage" }, - { 0x82, DBVT_WORD, "CompanyIndustry" }, - { 0xAA, DBVT_UTF8, "CompanyStreet" }, - { 0xB4, DBVT_UTF8, "CompanyCity" }, - { 0xBE, DBVT_UTF8, "CompanyState" }, - { 0xC8, DBVT_UTF8, "CompanyZIP" }, - { 0xD2, DBVT_WORD, "CompanyCountry" } -}; - -UserInfoRecordItem rEducation[] = -{ - { 0x64, DBVT_WORD, "StudyLevel" }, - { 0x6E, DBVT_UTF8, "StudyInstitute" }, - { 0x78, DBVT_UTF8, "StudyDegree" }, - { 0x8C, DBVT_WORD, "StudyYear" } -}; - -UserInfoRecordItem rInterest[] = -{ - { 0x64, DBVT_UTF8, "Interest%uText" }, - { 0x6E, DBVT_WORD, "Interest%uCat" } -}; - -int CIcqProto::parseUserInfoRecord(MCONTACT hContact, oscar_tlv *pData, UserInfoRecordItem pRecordDef[], int nRecordDef, int nMaxRecords) -{ - int nRecords = 0; - - if (pData && pData->wLen >= 2) { - BYTE *pRecords = pData->pData; - WORD wRecordCount; - unpackWord(&pRecords, &wRecordCount); - oscar_tlv_record_list *cData = readIntoTLVRecordList(&pRecords, pData->wLen - 2, nMaxRecords > wRecordCount ? wRecordCount : nMaxRecords); - oscar_tlv_record_list *cDataItem = cData; - while (cDataItem) { - oscar_tlv_chain *cItem = cDataItem->item; - - for (int i = 0; i < nRecordDef; i++) { - char szItemKey[MAX_PATH]; - mir_snprintf(szItemKey, pRecordDef[i].szDbSetting, nRecords); - - switch (pRecordDef[i].dbType) { - case DBVT_UTF8: - writeDbInfoSettingTLVStringUtf(hContact, szItemKey, cItem, pRecordDef[i].wTLV); - break; - - case DBVT_WORD: - writeDbInfoSettingTLVWord(hContact, szItemKey, cItem, pRecordDef[i].wTLV); - break; - } - } - nRecords++; - - cDataItem = cDataItem->next; - } - // release memory - disposeRecordList(&cData); - } - - // remove old data from database - if (!nRecords || nMaxRecords > 1) - for (int i = nRecords; i <= nMaxRecords; i++) - for (int j = 0; j < nRecordDef; j++) { - char szItemKey[MAX_PATH]; - mir_snprintf(szItemKey, pRecordDef[j].szDbSetting, i); - delSetting(hContact, szItemKey); - } - - return nRecords; -} - - -void CIcqProto::handleDirectoryQueryResponse(BYTE *databuf, size_t wPacketLen, WORD wCookie, WORD wReplySubtype, WORD wFlags) -{ - WORD wBytesRemaining = 0; - snac_header requestSnac = { 0 }; - BYTE requestResult; - - debugLogA("Received directory query response"); - - if (wPacketLen >= 2) - unpackLEWord(&databuf, &wBytesRemaining); - wPacketLen -= 2; - _ASSERTE(wPacketLen == wBytesRemaining); - - if (!unpackSnacHeader(&requestSnac, &databuf, &wPacketLen) || !requestSnac.bValid) { - debugLogA("Error: Failed to parse directory response"); - return; - } - - cookie_directory_data *pCookieData; - MCONTACT hContact; - // check request cookie - if (!FindCookie(wCookie, &hContact, (void**)&pCookieData) || !pCookieData) { - debugLogA("Warning: Ignoring unrequested directory reply type (x%x, x%x)", requestSnac.wFamily, requestSnac.wSubtype); - return; - } - /// FIXME: we should really check the snac contents according to cookie data here ?? - - // Check if this is the last packet for this request - BOOL bMoreDataFollows = wFlags & 0x0001 && requestSnac.wFlags & 0x0001; - - if (wPacketLen >= 3) - unpackByte(&databuf, &requestResult); - else { - debugLogA("Error: Malformed directory response"); - if (!bMoreDataFollows) - ReleaseCookie(wCookie); - return; - } - - if (requestResult != 1 && requestResult != 4) { - debugLogA("Error: Directory request failed, status %u", requestResult); - - if (!bMoreDataFollows) { - if (pCookieData->bRequestType == DIRECTORYREQUEST_INFOUSER) - ProtoBroadcastAck(hContact, ACKTYPE_GETINFO, ACKRESULT_FAILED, (HANDLE)1, 0); - else if (pCookieData->bRequestType == DIRECTORYREQUEST_SEARCH) - ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)wCookie, 0); // should report error here, but Find/Add module does not support that - ReleaseCookie(wCookie); - } - return; - } - - size_t wLen; - unpackWord(&databuf, &wLen); - wPacketLen -= 3; - if (wLen) - debugLogA("Warning: Data in error message present!"); - - if (wPacketLen <= 0x16) { // sanity check - debugLogA("Error: Malformed directory response"); - - if (!bMoreDataFollows) { - if (pCookieData->bRequestType == DIRECTORYREQUEST_INFOUSER) - ProtoBroadcastAck(hContact, ACKTYPE_GETINFO, ACKRESULT_FAILED, (HANDLE)1, 0); - else if (pCookieData->bRequestType == DIRECTORYREQUEST_SEARCH) - ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)wCookie, 0); // should report error here, but Find/Add module does not support that - ReleaseCookie(wCookie); - } - return; - } - databuf += 0x10; // unknown stuff - wPacketLen -= 0x10; - - DWORD dwItemCount; - WORD wPageCount; - - /// FIXME: check itemcount, pagecount against the cookie data ??? - - unpackDWord(&databuf, &dwItemCount); - unpackWord(&databuf, &wPageCount); - wPacketLen -= 6; - - if (pCookieData->bRequestType == DIRECTORYREQUEST_SEARCH && !bMoreDataFollows) - debugLogA("Directory Search: %d contacts found (%u pages)", dwItemCount, wPageCount); - - if (wPacketLen <= 2) { // sanity check, block expected - debugLogA("Error: Malformed directory response"); - - if (!bMoreDataFollows) { - if (pCookieData->bRequestType == DIRECTORYREQUEST_INFOUSER) - ProtoBroadcastAck(hContact, ACKTYPE_GETINFO, ACKRESULT_FAILED, (HANDLE)1, 0); - else if (pCookieData->bRequestType == DIRECTORYREQUEST_SEARCH) - ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)wCookie, 0); // should report error here, but Find/Add module does not support that - ReleaseCookie(wCookie); - } - return; - } - - WORD wData; - unpackWord(&databuf, &wData); // This probably the count of items following (a block) - wPacketLen -= 2; - if (wPacketLen >= 2 && wData >= 1) { - unpackWord(&databuf, &wLen); // This is the size of the first item - wPacketLen -= 2; - } - - if (wData == 0 && pCookieData->bRequestType == DIRECTORYREQUEST_SEARCH) { - debugLogA("Directory Search: No contacts found"); - ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)wCookie, 0); - ReleaseCookie(wCookie); - return; - } - - _ASSERTE(wData == 1 && wPacketLen == wLen); - if (wData != 1 || wPacketLen != wLen) { - debugLogA("Error: Malformed directory response (missing data)"); - - if (!bMoreDataFollows) { - if (pCookieData->bRequestType == DIRECTORYREQUEST_INFOUSER) - ProtoBroadcastAck(hContact, ACKTYPE_GETINFO, ACKRESULT_FAILED, (HANDLE)1, 0); - else if (pCookieData->bRequestType == DIRECTORYREQUEST_SEARCH) - ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)wCookie, 0); // should report error here, but Find/Add module does not support that - ReleaseCookie(wCookie); - } - return; - } - - oscar_tlv_chain *pDirectoryData = readIntoTLVChain(&databuf, wLen, -1); - if (pDirectoryData) { - switch (pCookieData->bRequestType) { - case DIRECTORYREQUEST_INFOOWNER: - parseDirectoryUserDetailsData(NULL, pDirectoryData, pCookieData, wReplySubtype); - break; - - case DIRECTORYREQUEST_INFOUSER: - { - DWORD dwUin = 0; - char *szUid = pDirectoryData->getString(0x32, 1); - if (!szUid) { - debugLogA("Error: Received unrecognized data from the directory"); - break; - } - - if (IsStringUIN(szUid)) - dwUin = atoi(szUid); - - if (hContact != HContactFromUID(dwUin, szUid, nullptr)) { - debugLogA("Error: Received data does not match cookie contact, ignoring."); - SAFE_FREE(&szUid); - break; - } - else SAFE_FREE(&szUid); - } - - case DIRECTORYREQUEST_INFOMULTI: - parseDirectoryUserDetailsData(hContact, pDirectoryData, pCookieData, wReplySubtype); - break; - - case DIRECTORYREQUEST_SEARCH: - parseDirectorySearchData(pDirectoryData, wCookie, wReplySubtype); - break; - - default: - debugLogA("Error: Unknown cookie type %x for directory response!", pCookieData->bRequestType); - } - disposeChain(&pDirectoryData); - } - else debugLogA("Error: Failed parsing directory response"); - - // Release Memory - if (!bMoreDataFollows) - ReleaseCookie(wCookie); -} - -static int calcAgeFromBirthDate(double dDate) -{ - if (dDate > 0) { // date is stored as double with unit equal to a day, incrementing since 1/1/1900 0:00 GMT - SYSTEMTIME sDate = { 0 }; - if (VariantTimeToSystemTime(dDate + 2, &sDate)) { - SYSTEMTIME sToday = { 0 }; - GetLocalTime(&sToday); - - int nAge = sToday.wYear - sDate.wYear; - if (sToday.wMonth < sDate.wMonth || (sToday.wMonth == sDate.wMonth && sToday.wDay < sDate.wDay)) - nAge--; - - return nAge; - } - } - return 0; -} - -void CIcqProto::parseDirectoryUserDetailsData(MCONTACT hContact, oscar_tlv_chain *cDetails, cookie_directory_data *pCookieData, WORD wReplySubType) -{ - if (pCookieData->bRequestType == DIRECTORYREQUEST_INFOMULTI && !hContact) { - DWORD dwUin = 0; - char *szUid = cDetails->getString(0x32, 1); - if (!szUid) { - debugLogA("Error: Received unrecognized data from the directory"); - return; - } - - if (IsStringUIN(szUid)) - dwUin = atoi(szUid); - - hContact = HContactFromUID(dwUin, szUid, nullptr); - if (hContact == INVALID_CONTACT_ID) { - debugLogA("Error: Received details for unknown contact \"%s\"", szUid); - SAFE_FREE(&szUid); - return; - } - - debugLogA("Received user info for %s from directory", szUid); - SAFE_FREE(&szUid); - } - - oscar_tlv *pTLV = cDetails->getTLV(0x50, 1); - if (pTLV && pTLV->wLen > 0) - writeDbInfoSettingTLVStringUtf(hContact, "e-mail", cDetails, 0x50); // Verified e-mail - else - writeDbInfoSettingTLVStringUtf(hContact, "e-mail", cDetails, 0x55); // Pending e-mail - - writeDbInfoSettingTLVStringUtf(hContact, "FirstName", cDetails, 0x64); - writeDbInfoSettingTLVStringUtf(hContact, "LastName", cDetails, 0x6E); - writeDbInfoSettingTLVStringUtf(hContact, "Nick", cDetails, 0x78); - // Home Address - parseUserInfoRecord(hContact, cDetails->getTLV(0x96, 1), rAddress, _countof(rAddress), 1); - // Origin Address - parseUserInfoRecord(hContact, cDetails->getTLV(0xA0, 1), rOriginAddress, _countof(rOriginAddress), 1); - // Phones - pTLV = cDetails->getTLV(0xC8, 1); - if (pTLV && pTLV->wLen >= 2) { - BYTE *pRecords = pTLV->pData; - WORD wRecordCount; - unpackWord(&pRecords, &wRecordCount); - oscar_tlv_record_list *cPhones = readIntoTLVRecordList(&pRecords, pTLV->wLen - 2, wRecordCount); - if (cPhones) { - oscar_tlv_chain *cPhone; - cPhone = cPhones->getRecordByTLV(0x6E, 1); - writeDbInfoSettingTLVStringUtf(hContact, "Phone", cPhone, 0x64); - cPhone = cPhones->getRecordByTLV(0x6E, 2); - writeDbInfoSettingTLVStringUtf(hContact, "CompanyPhone", cPhone, 0x64); - cPhone = cPhones->getRecordByTLV(0x6E, 3); - writeDbInfoSettingTLVStringUtf(hContact, "Cellular", cPhone, 0x64); - cPhone = cPhones->getRecordByTLV(0x6E, 4); - writeDbInfoSettingTLVStringUtf(hContact, "Fax", cPhone, 0x64); - cPhone = cPhones->getRecordByTLV(0x6E, 5); - writeDbInfoSettingTLVStringUtf(hContact, "CompanyFax", cPhone, 0x64); - - disposeRecordList(&cPhones); - } - else { // Remove old data when phones not available - delSetting(hContact, "Phone"); - delSetting(hContact, "CompanyPhone"); - delSetting(hContact, "Cellular"); - delSetting(hContact, "Fax"); - delSetting(hContact, "CompanyFax"); - } - } - else { // Remove old data when phones not available - delSetting(hContact, "Phone"); - delSetting(hContact, "CompanyPhone"); - delSetting(hContact, "Cellular"); - delSetting(hContact, "Fax"); - delSetting(hContact, "CompanyFax"); - } - // Emails - parseUserInfoRecord(hContact, cDetails->getTLV(0x8C, 1), rEmail, _countof(rEmail), 4); - - writeDbInfoSettingTLVByte(hContact, "Timezone", cDetails, 0x17C); - // Company - parseUserInfoRecord(hContact, cDetails->getTLV(0x118, 1), rCompany, _countof(rCompany), 1); - // Education - parseUserInfoRecord(hContact, cDetails->getTLV(0x10E, 1), rEducation, _countof(rEducation), 1); - - switch (cDetails->getNumber(0x82, 1)) { - case 1: - setByte(hContact, "Gender", 'F'); - break; - case 2: - setByte(hContact, "Gender", 'M'); - break; - default: - delSetting(hContact, "Gender"); - } - - writeDbInfoSettingTLVStringUtf(hContact, "Homepage", cDetails, 0xFA); - writeDbInfoSettingTLVDate(hContact, "BirthYear", "BirthMonth", "BirthDay", cDetails, 0x1A4); - - writeDbInfoSettingTLVByte(hContact, "Language1", cDetails, 0xAA); - writeDbInfoSettingTLVByte(hContact, "Language2", cDetails, 0xB4); - writeDbInfoSettingTLVByte(hContact, "Language3", cDetails, 0xBE); - - writeDbInfoSettingTLVByte(hContact, "MaritalStatus", cDetails, 0x12C); - // Interests - parseUserInfoRecord(hContact, cDetails->getTLV(0x122, 1), rInterest, _countof(rInterest), 4); - - writeDbInfoSettingTLVStringUtf(hContact, "About", cDetails, 0x186); - - // if (hContact) - // writeDbInfoSettingTLVStringUtf(hContact, DBSETTING_STATUS_NOTE, cDetails, 0x226); - // else - if (!hContact) { // Owner contact needs special processing, in the database is current status note for the client - // We just received the last status note set on directory, if it differs call SetStatusNote() to - // ensure the directory will be updated (it should be in process anyway) - char *szClientStatusNote = getSettingStringUtf(hContact, DBSETTING_STATUS_NOTE, nullptr); - char *szDirectoryStatusNote = cDetails->getString(0x226, 1); - - if (mir_strcmp(szClientStatusNote, szDirectoryStatusNote)) - SetStatusNote(szClientStatusNote, 1000, TRUE); - - // Release memory - SAFE_FREE(&szDirectoryStatusNote); - SAFE_FREE(&szClientStatusNote); - } - - writeDbInfoSettingTLVByte(hContact, "PrivacyLevel", cDetails, 0x1F9); - - if (!hContact) { - setByte(hContact, "Auth", !cDetails->getByte(0x19A, 1)); - writeDbInfoSettingTLVByte(hContact, "WebAware", cDetails, 0x212); - writeDbInfoSettingTLVByte(hContact, "AllowSpam", cDetails, 0x1EA); - } - - writeDbInfoSettingTLVWord(hContact, "InfoCP", cDetails, 0x1C2); - - if (hContact) { // Handle deprecated setting (Age & Birthdate are not separate fields anymore) - int nAge = calcAgeFromBirthDate(cDetails->getDouble(0x1A4, 1)); - - if (nAge) - setWord(hContact, "Age", nAge); - else - delSetting(hContact, "Age"); - } - else // we do not need to calculate age for owner - delSetting(hContact, "Age"); - - { // Save user info last update time and privacy token - double dInfoTime; - BYTE pbEmptyMetaToken[0x10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - int bHasMetaToken = FALSE; - - // Check if the details arrived with privacy token! - if ((pTLV = cDetails->getTLV(0x3C, 1)) && pTLV->wLen == 0x10 && memcmp(pTLV->pData, pbEmptyMetaToken, 0x10)) - bHasMetaToken = TRUE; - - // !Important, we need to save the MDir server-item time - it can be newer than the one from the directory - if ((dInfoTime = getSettingDouble(hContact, DBSETTING_METAINFO_TIME, 0)) > 0) - setSettingDouble(hContact, DBSETTING_METAINFO_SAVED, dInfoTime); - else if (bHasMetaToken || !hContact) - writeDbInfoSettingTLVDouble(hContact, DBSETTING_METAINFO_SAVED, cDetails, 0x1CC); - else - setDword(hContact, DBSETTING_METAINFO_SAVED, time(0)); - } - - if (wReplySubType == META_DIRECTORY_RESPONSE) - if (pCookieData->bRequestType == DIRECTORYREQUEST_INFOUSER) - ProtoBroadcastAck(hContact, ACKTYPE_GETINFO, ACKRESULT_SUCCESS, (HANDLE)1, 0); - - // Remove user from info update queue. Removing is fast so we always call this - // even if it is likely that the user is not queued at all. - if (hContact) - icq_DequeueUser(getContactUin(hContact)); -} - - -void CIcqProto::parseDirectorySearchData(oscar_tlv_chain *cDetails, DWORD dwCookie, WORD wReplySubType) -{ - char *szUid = cDetails->getString(0x32, 1); // User ID - - debugLogA("Directory Search: Found user %s", szUid); - - ICQSEARCHRESULT isr = { 0 }; - isr.hdr.cbSize = sizeof(ICQSEARCHRESULT); - isr.hdr.flags = PSR_UTF8; - isr.hdr.id.a = szUid; - - if (IsStringUIN(szUid)) - isr.uin = atoi(szUid); - else - isr.uin = 0; - - oscar_tlv *pTLV = cDetails->getTLV(0x50, 1); - char *szData = nullptr; - - if (pTLV && pTLV->wLen > 0) - szData = cDetails->getString(0x50, 1); // Verified e-mail - else - szData = cDetails->getString(0x55, 1); // Pending e-mail - if (szData != nullptr) - isr.hdr.email.a = szData; - - szData = cDetails->getString(0x64, 1); // First Name - if (szData != nullptr) - isr.hdr.firstName.a = szData; - - szData = cDetails->getString(0x6E, 1); // Last Name - if (szData != nullptr) - isr.hdr.lastName.a = szData; - - szData = cDetails->getString(0x78, 1); // Nick - if (szData != nullptr) - isr.hdr.nick.a = szData; - - switch (cDetails->getNumber(0x82, 1)) { // Gender - case 1: - isr.gender = 'F'; - break; - case 2: - isr.gender = 'M'; - break; - } - - pTLV = cDetails->getTLV(0x96, 1); - if (pTLV && pTLV->wLen >= 4) { - BYTE *buf = pTLV->pData; - oscar_tlv_chain *chain = readIntoTLVChain(&buf, pTLV->wLen, 0); - if (chain) - isr.country = chain->getDWord(0x8C, 1); // Home Country - disposeChain(&chain); - } - - isr.auth = !cDetails->getByte(0x19A, 1); // Require Authorization - isr.maritalStatus = cDetails->getNumber(0x12C, 1); // Marital Status - - // calculate Age if Birthdate is available - isr.age = calcAgeFromBirthDate(cDetails->getDouble(0x1A4, 1)); - - // Finally, broadcast the result - ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)dwCookie, (LPARAM)&isr); - - // Release memory - SAFE_FREE(&isr.hdr.id.a); - SAFE_FREE(&isr.hdr.nick.a); - SAFE_FREE(&isr.hdr.firstName.a); - SAFE_FREE(&isr.hdr.lastName.a); - SAFE_FREE(&isr.hdr.email.a); - - // Search is over, broadcast final ack - if (wReplySubType == META_DIRECTORY_RESPONSE) - ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)dwCookie, 0); -} - - -void CIcqProto::handleDirectoryUpdateResponse(BYTE *databuf, size_t wPacketLen, WORD wCookie) -{ - WORD wBytesRemaining = 0; - snac_header requestSnac = { 0 }; - BYTE requestResult; - - debugLogA("Received directory update response"); - - if (wPacketLen >= 2) - unpackLEWord(&databuf, &wBytesRemaining); - wPacketLen -= 2; - _ASSERTE(wPacketLen == wBytesRemaining); - - if (!unpackSnacHeader(&requestSnac, &databuf, &wPacketLen) || !requestSnac.bValid) { - debugLogA("Error: Failed to parse directory response"); - return; - } - - cookie_directory_data *pCookieData; - MCONTACT hContact; - // check request cookie - if (!FindCookie(wCookie, &hContact, (void**)&pCookieData) || !pCookieData) { - debugLogA("Warning: Ignoring unrequested directory reply type (x%x, x%x)", requestSnac.wFamily, requestSnac.wSubtype); - return; - } - /// FIXME: we should really check the snac contents according to cookie data here ?? - - if (wPacketLen >= 3) - unpackByte(&databuf, &requestResult); - else { - debugLogA("Error: Malformed directory response"); - ReleaseCookie(wCookie); - return; - } - if (requestResult != 1 && requestResult != 4) { - debugLogA("Error: Directory request failed, status %u", requestResult); - - if (pCookieData->bRequestType == DIRECTORYREQUEST_UPDATEOWNER) - ProtoBroadcastAck(NULL, ACKTYPE_SETINFO, ACKRESULT_FAILED, (HANDLE)wCookie, 0); - - ReleaseCookie(wCookie); - return; - } - size_t wLen; - - unpackWord(&databuf, &wLen); - wPacketLen -= 3; - if (wLen) - debugLogA("Warning: Data in error message present!"); - - if (pCookieData->bRequestType == DIRECTORYREQUEST_UPDATEOWNER) - ProtoBroadcastAck(NULL, ACKTYPE_SETINFO, ACKRESULT_SUCCESS, (HANDLE)wCookie, 0); - if (wPacketLen == 0x18) { - DWORD64 qwMetaTime; - BYTE pbEmptyMetaToken[0x10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - - unpackQWord(&databuf, &qwMetaTime); - setSettingBlob(NULL, DBSETTING_METAINFO_TIME, (BYTE*)&qwMetaTime, 8); - - if (memcmp(databuf, pbEmptyMetaToken, 0x10)) - setSettingBlob(NULL, DBSETTING_METAINFO_TOKEN, databuf, 0x10); - } - ReleaseCookie(wCookie); -} diff --git a/protocols/IcqOscarJ/src/fam_17signon.cpp b/protocols/IcqOscarJ/src/fam_17signon.cpp deleted file mode 100644 index b4bc11a249..0000000000 --- a/protocols/IcqOscarJ/src/fam_17signon.cpp +++ /dev/null @@ -1,161 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2009 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -void CIcqProto::handleAuthorizationFam(BYTE *pBuffer, size_t wBufferLength, snac_header *pSnacHeader, serverthread_info *info) -{ - switch (pSnacHeader->wSubtype) { - - case ICQ_SIGNON_ERROR: - { - WORD wError; - - if (wBufferLength >= 2) - unpackWord(&pBuffer, &wError); - else - wError = 0; - - LogFamilyError(ICQ_AUTHORIZATION_FAMILY, wError); - break; - } - - case ICQ_SIGNON_AUTH_KEY: - handleAuthKeyResponse(pBuffer, wBufferLength, info); - break; - - case ICQ_SIGNON_LOGIN_REPLY: - handleLoginReply(pBuffer, wBufferLength, info); - break; - - default: - debugLogA("Warning: Ignoring SNAC(x%02x,x%02x) - Unknown SNAC (Flags: %u, Ref: %u)", ICQ_AUTHORIZATION_FAMILY, pSnacHeader->wSubtype, pSnacHeader->wFlags, pSnacHeader->dwRef); - break; - } -} - -static void icq_encryptPassword(const char *szPassword, BYTE *encrypted) -{ - BYTE table[] = - { - 0xf3, 0x26, 0x81, 0xc4, - 0x39, 0x86, 0xdb, 0x92, - 0x71, 0xa3, 0xb9, 0xe6, - 0x53, 0x7a, 0x95, 0x7c - }; - - for (int i = 0; szPassword[i]; i++) - encrypted[i] = (szPassword[i] ^ table[i % 16]); -} - -void CIcqProto::sendClientAuth(const char *szKey, size_t wKeyLen, BOOL bSecure) -{ - char szUin[UINMAXLEN]; - icq_packet packet; - - size_t wUinLen = mir_strlen(strUID(m_dwLocalUIN, szUin)); - - packet.wLen = WORD((m_bLegacyFix ? 65 : 70) + sizeof(CLIENT_ID_STRING) + wUinLen + wKeyLen + (m_bSecureConnection ? 4 : 0)); - - if (bSecure) { - serverPacketInit(&packet, packet.wLen + 10); - packFNACHeader(&packet, ICQ_AUTHORIZATION_FAMILY, ICQ_SIGNON_LOGIN_REQUEST, 0, 0); - } - else { - write_flap(&packet, ICQ_LOGIN_CHAN); - packDWord(&packet, 0x00000001); - } - packTLV(&packet, 0x0001, wUinLen, (LPBYTE)szUin); - - if (bSecure) { // Pack MD5 auth digest - packTLV(&packet, 0x0025, wKeyLen, (BYTE*)szKey); - packDWord(&packet, 0x004C0000); // empty TLV(0x4C): unknown - } - else { // Pack old style password hash - BYTE hash[20]; - - icq_encryptPassword(szKey, hash); - packTLV(&packet, 0x0002, wKeyLen, hash); - } - - // Pack client identification details. - packTLV(&packet, 0x0003, (WORD)sizeof(CLIENT_ID_STRING) - 1, (LPBYTE)CLIENT_ID_STRING); - packTLVWord(&packet, 0x0017, CLIENT_VERSION_MAJOR); - packTLVWord(&packet, 0x0018, CLIENT_VERSION_MINOR); - packTLVWord(&packet, 0x0019, CLIENT_VERSION_LESSER); - packTLVWord(&packet, 0x001a, CLIENT_VERSION_BUILD); - packTLVWord(&packet, 0x0016, CLIENT_ID_CODE); - packTLVDWord(&packet, 0x0014, CLIENT_DISTRIBUTION); - packTLV(&packet, 0x000f, 0x0002, (LPBYTE)CLIENT_LANGUAGE); - packTLV(&packet, 0x000e, 0x0002, (LPBYTE)CLIENT_COUNTRY); - if (!m_bLegacyFix) - packTLV(&packet, 0x0094, 0x0001, &m_bConnectionLost); // CLIENT_RECONNECT flag - if (m_bSecureConnection) - packDWord(&packet, 0x008C0000); // empty TLV(0x8C): use SSL - - sendServPacket(&packet); -} - -void CIcqProto::handleAuthKeyResponse(BYTE *buf, size_t wPacketLen, serverthread_info *info) -{ - char szKey[64] = { 0 }; - mir_md5_state_t state; - BYTE digest[16]; - - debugLogA("Received %s", "ICQ_SIGNON_AUTH_KEY"); - - if (wPacketLen < 2) { - debugLogA("Malformed %s", "ICQ_SIGNON_AUTH_KEY"); - icq_LogMessage(LOG_FATAL, LPGEN("Secure login failed.\nInvalid server response.")); - SetCurrentStatus(ID_STATUS_OFFLINE); - return; - } - - size_t wKeyLen; - unpackWord(&buf, &wKeyLen); - wPacketLen -= 2; - - if (!wKeyLen || wKeyLen > wPacketLen || wKeyLen > sizeof(szKey)) { - debugLogA("Invalid length in %s: %u", "ICQ_SIGNON_AUTH_KEY", wKeyLen); - icq_LogMessage(LOG_FATAL, LPGEN("Secure login failed.\nInvalid key length.")); - SetCurrentStatus(ID_STATUS_OFFLINE); - return; - } - - unpackString(&buf, szKey, wKeyLen); - - mir_md5_init(&state); - mir_md5_append(&state, info->szAuthKey, (int)info->wAuthKeyLen); - mir_md5_finish(&state, digest); - - mir_md5_init(&state); - mir_md5_append(&state, (LPBYTE)szKey, (int)wKeyLen); - mir_md5_append(&state, digest, 16); - mir_md5_append(&state, (LPBYTE)CLIENT_MD5_STRING, sizeof(CLIENT_MD5_STRING) - 1); - mir_md5_finish(&state, digest); - - debugLogA("Sending ICQ_SIGNON_LOGIN_REQUEST to login server"); - sendClientAuth((char*)digest, 0x10, TRUE); -} diff --git a/protocols/IcqOscarJ/src/families.h b/protocols/IcqOscarJ/src/families.h deleted file mode 100644 index 7ca934ab1c..0000000000 --- a/protocols/IcqOscarJ/src/families.h +++ /dev/null @@ -1,73 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// Declaration for handlers of Channel 2 SNAC Families -// ----------------------------------------------------------------------------- - -#ifndef __FAMILIES_H -#define __FAMILIES_H - -struct message_ack_params -{ - BYTE bType; - DWORD dwUin; - DWORD dwMsgID1; - DWORD dwMsgID2; - directconnect *pDC; - WORD wCookie; - int msgType; - BYTE bFlags; -}; - -#define MAT_SERVER_ADVANCED 0 -#define MAT_DIRECT 1 - - -/* handleMessageTypes(): mMsgFlags constants */ -#define MTF_DIRECT 1 -#define MTF_PLUGIN 2 -#define MTF_STATUS_EXTENDED 4 - - -struct UserInfoRecordItem -{ - WORD wTLV; - int dbType; - char *szDbSetting; -}; - -/*---------* Functions *---------------*/ - -int getPluginTypeIdLen(int nTypeID); -void packPluginTypeId(icq_packet *packet, int nTypeID); - -#define BUL_ALLCONTACTS 0 -#define BUL_VISIBLE 1 -#define BUL_INVISIBLE 2 -#define BUL_TEMPVISIBLE 4 - - -#endif /* __FAMILIES_H */ diff --git a/protocols/IcqOscarJ/src/globals.h b/protocols/IcqOscarJ/src/globals.h deleted file mode 100644 index 84769644c9..0000000000 --- a/protocols/IcqOscarJ/src/globals.h +++ /dev/null @@ -1,59 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// Contains global types & variables declarations. -// -// ----------------------------------------------------------------------------- - -#ifndef __GLOBALS_H -#define __GLOBALS_H - - -typedef char uid_str[MAX_PATH]; - -// from init.cpp -extern DWORD MIRANDA_VERSION; - -extern HANDLE hExtraXStatus; - -extern const int moodXStatus[]; - -// from fam_04message.cpp -struct icq_mode_messages -{ - char *szOnline; - char *szAway; - char *szNa; - char *szDnd; - char *szOccupied; - char *szFfc; -}; - -void g_MenuInit(); -void g_MenuUninit(); - -#endif /* __GLOBALS_H */ diff --git a/protocols/IcqOscarJ/src/guids.h b/protocols/IcqOscarJ/src/guids.h deleted file mode 100644 index 7c5ba90686..0000000000 --- a/protocols/IcqOscarJ/src/guids.h +++ /dev/null @@ -1,76 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// Contains helper functions to handle oscar message GUIDs. -// ----------------------------------------------------------------------------- - -#ifndef __GUIDS_H -#define __GUIDS_H - -typedef DWORD plugin_guid[4]; - -// Message Capability GUIDs -static const plugin_guid MCAP_SRV_RELAY_FMT = { MCAP_SRV_RELAY_FMT_s }; -static const plugin_guid MCAP_REVERSE_DC_REQ = { MCAP_REVERSE_DC_REQ_s }; -static const plugin_guid MCAP_FILE_TRANSFER = { MCAP_FILE_TRANSFER_s }; -static const plugin_guid MCAP_CONTACTS = { MCAP_CONTACTS_s }; - -// Plugin GUIDs -static const plugin_guid PSIG_MESSAGE = { PSIG_MESSAGE_s }; -static const plugin_guid PSIG_INFO_PLUGIN = { PSIG_INFO_PLUGIN_s }; -static const plugin_guid PSIG_STATUS_PLUGIN = { PSIG_STATUS_PLUGIN_s }; - -// Plugin Message GUIDs -static const plugin_guid PMSG_QUERY_INFO = { PMSG_QUERY_INFO_s }; -static const plugin_guid PMSG_QUERY_STATUS = { PMSG_QUERY_STATUS_s }; - -// Message GUIDs -static const plugin_guid MGTYPE_MESSAGE = { MGTYPE_MESSAGE_s }; -static const plugin_guid MGTYPE_STATUSMSGEXT = { MGTYPE_STATUSMSGEXT_s }; -static const plugin_guid MGTYPE_FILE = { MGTYPE_FILE_s }; -static const plugin_guid MGTYPE_WEBURL = { MGTYPE_WEBURL_s }; -static const plugin_guid MGTYPE_CONTACTS = { MGTYPE_CONTACTS_s }; -static const plugin_guid MGTYPE_GREETING_CARD = { MGTYPE_GREETING_CARD_s }; -static const plugin_guid MGTYPE_CHAT = { MGTYPE_CHAT_s }; -static const plugin_guid MGTYPE_SMS_MESSAGE = { MGTYPE_SMS_MESSAGE_s }; -static const plugin_guid MGTYPE_XTRAZ_SCRIPT = { MGTYPE_XTRAZ_SCRIPT_s }; - -// make GUID checks easy -__forceinline bool CompareGUIDs(DWORD q1, DWORD q2, DWORD q3, DWORD q4, const plugin_guid guid) -{ - return ((q1 == guid[0]) && (q2 == guid[1]) && (q3 == guid[2]) && (q4 == guid[3])) ? true : false; -} - -// pack entire GUID into icq packet -static __inline void packGUID(icq_packet *packet, const plugin_guid guid) -{ - packDWord(packet, guid[0]); - packDWord(packet, guid[1]); - packDWord(packet, guid[2]); - packDWord(packet, guid[3]); -} - -#endif /* __GUIDS_H */ diff --git a/protocols/IcqOscarJ/src/i18n.cpp b/protocols/IcqOscarJ/src/i18n.cpp deleted file mode 100644 index 76fdf8a09c..0000000000 --- a/protocols/IcqOscarJ/src/i18n.cpp +++ /dev/null @@ -1,499 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// Contains helper functions to convert text messages between different -// character sets. -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -static BOOL bHasCP_UTF8 = FALSE; - -void InitI18N(void) -{ - CPINFO CPInfo; - bHasCP_UTF8 = GetCPInfo(CP_UTF8, &CPInfo); -} - -// Returns true if the buffer only contains 7-bit characters. -BOOL __stdcall IsUSASCII(const char *pBuffer, size_t nSize) -{ - for (size_t nIndex = 0; nIndex < nSize; nIndex++) - if (BYTE(pBuffer[nIndex]) > 0x7F) - return FALSE; - - return TRUE; -} - -// Returns true if the unicode buffer only contains 7-bit characters. -BOOL __stdcall IsUnicodeAscii(const WCHAR *pBuffer, size_t nSize) -{ - for (size_t nIndex = 0; nIndex < nSize; nIndex++) - if (WORD(pBuffer[nIndex]) > 0x7F) - return FALSE; - - return TRUE; -} - - -// Scans a string encoded in UTF-8 to verify that it contains -// only valid sequences. It will return 1 if the string contains -// only legitimate encoding sequences; otherwise it will return 0; -// From 'Secure Programming Cookbook', John Viega & Matt Messier, 2003 -int __stdcall UTF8_IsValid(const char *pszInput) -{ - int nb; - if (!pszInput) - return 0; - - for (BYTE* c = (BYTE*)pszInput; *c; c += (nb + 1)) { - if (!(*c & 0x80)) - nb = 0; - else if ((*c & 0xc0) == 0x80) return 0; - else if ((*c & 0xe0) == 0xc0) nb = 1; - else if ((*c & 0xf0) == 0xe0) nb = 2; - else if ((*c & 0xf8) == 0xf0) nb = 3; - else if ((*c & 0xfc) == 0xf8) nb = 4; - else if ((*c & 0xfe) == 0xfc) nb = 5; - else nb = 0; - - for (int i = 1; i <= nb; i++) // we this forward, do not cross end of string - if ((*(c + i) & 0xc0) != 0x80) - return 0; - } - - return 1; -} - - -int __stdcall get_utf8_size(const WCHAR *unicode) -{ - int size = 0; - int index = 0; - /* calculate the size of the utf-8 string */ - WCHAR c = unicode[index++]; - while (c) { - if (c < 0x0080) - size += 1; - else if (c < 0x0800) - size += 2; - else - size += 3; - c = unicode[index++]; - } - return size; -} - - -// returns ansi string in all cases -char* __stdcall detect_decode_utf8(const char *from) -{ - char *temp = nullptr; - - if (IsUSASCII(from, mir_strlen(from)) || !UTF8_IsValid(from) || !utf8_decode(from, &temp)) return (char*)from; - SAFE_FREE((void**)&from); - - return temp; -} - - -/* -* The following UTF8 routines are -* -* Copyright (C) 2001 Peter Harris -* Copyright (C) 2001 Edmund Grimley Evans -* -* under a GPL license -* -* -------------------------------------------------------------- -* Convert a string between UTF-8 and the locale's charset. -* Invalid bytes are replaced by '#', and characters that are -* not available in the target encoding are replaced by '?'. -* -* If the locale's charset is not set explicitly then it is -* obtained using nl_langinfo(CODESET), where available, the -* environment variable CHARSET, or assumed to be US-ASCII. -* -* Return value of conversion functions: -* -* -1 : memory allocation failed -* 0 : data was converted exactly -* 1 : valid data was converted approximately (using '?') -* 2 : input was invalid (but still converted, using '#') -* 3 : unknown encoding (but still converted, using '?') -*/ - - - -/* -* Convert a string between UTF-8 and the locale's charset. -*/ -char* __stdcall make_utf8_string_static(const WCHAR *unicode, char *utf8, size_t utf_size) -{ - int index = 0; - unsigned int out_index = 0; - unsigned short c; - - c = unicode[index++]; - while (c) { - if (c < 0x080) { - if (out_index + 1 >= utf_size) break; - utf8[out_index++] = (unsigned char)c; - } - else if (c < 0x800) { - if (out_index + 2 >= utf_size) break; - utf8[out_index++] = 0xc0 | (c >> 6); - utf8[out_index++] = 0x80 | (c & 0x3f); - } - else { - if (out_index + 3 >= utf_size) break; - utf8[out_index++] = 0xe0 | (c >> 12); - utf8[out_index++] = 0x80 | ((c >> 6) & 0x3f); - utf8[out_index++] = 0x80 | (c & 0x3f); - } - c = unicode[index++]; - } - utf8[out_index] = 0x00; - - return utf8; -} - - -char* __stdcall make_utf8_string(const WCHAR *unicode) -{ - if (!unicode) return nullptr; - - /* first calculate the size of the target string */ - size_t size = get_utf8_size(unicode); - - char *out = (char*)SAFE_MALLOC(size + 1); - if (!out) - return nullptr; - - return make_utf8_string_static(unicode, out, size + 1); -} - - -WCHAR* __stdcall make_unicode_string_static(const char *utf8, WCHAR *unicode, size_t unicode_size) -{ - unsigned int out_index = 0; - - if (utf8) { - unsigned int index = 0; - unsigned char c = utf8[index++]; - - while (c) { - if (out_index + 1 >= unicode_size) break; - if ((c & 0x80) == 0) { - unicode[out_index++] = c; - } - else if ((c & 0xe0) == 0xe0) { - unicode[out_index] = (c & 0x1F) << 12; - c = utf8[index++]; - unicode[out_index] |= (c & 0x3F) << 6; - c = utf8[index++]; - unicode[out_index++] |= (c & 0x3F); - } - else { - unicode[out_index] = (c & 0x3F) << 6; - c = utf8[index++]; - unicode[out_index++] |= (c & 0x3F); - } - c = utf8[index++]; - } - } - unicode[out_index] = 0; - - return unicode; -} - - -WCHAR* __stdcall make_unicode_string(const char *utf8) -{ - int size = 0, index = 0; - - if (!utf8) return nullptr; - - /* first calculate the size of the target string */ - unsigned char c = utf8[index++]; - while (c) { - if ((c & 0x80) == 0) { - index += 0; - } - else if ((c & 0xe0) == 0xe0) { - index += 2; - } - else { - index += 1; - } - size += 1; - c = utf8[index++]; - } - - WCHAR *out = (WCHAR*)SAFE_MALLOC((size + 1) * sizeof(WCHAR)); - if (!out) - return nullptr; - else - return make_unicode_string_static(utf8, out, size + 1); -} - - -int __stdcall utf8_encode(const char *from, char **to) -{ - int wchars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, from, (int)mir_strlen(from), nullptr, 0); - - if (wchars == 0) { -#ifdef _DEBUG - fprintf(stderr, "Unicode translation error %d\n", GetLastError()); -#endif - return -1; - } - - WCHAR *unicode = (WCHAR*)_alloca((wchars + 1) * sizeof(WCHAR)); - memset(unicode, 0, ((wchars + 1) * sizeof(WCHAR))); - - int err = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, from, (int)mir_strlen(from), unicode, wchars); - if (err != wchars) { -#ifdef _DEBUG - fprintf(stderr, "Unicode translation error %d\n", GetLastError()); -#endif - return -1; - } - - /* On NT-based windows systems, we could use WideCharToMultiByte(), but - * MS doesn't actually have a consistent API across win32. - */ - *to = make_utf8_string(unicode); - return 0; -} - - -char* __stdcall ansi_to_utf8(const char *ansi) -{ - char *szUtf = nullptr; - - if (mir_strlen(ansi)) { - utf8_encode(ansi, &szUtf); - return szUtf; - } - - return null_strdup(""); -} - - -char* __stdcall ansi_to_utf8_codepage(const char *ansi, WORD wCp) -{ - size_t wchars = mir_strlen(ansi); - WCHAR *unicode = (WCHAR*)_alloca((wchars + 1) * sizeof(WCHAR)); - memset(unicode, 0, ((wchars + 1) * sizeof(WCHAR))); - - MultiByteToWideChar(wCp, MB_PRECOMPOSED, ansi, (int)wchars, unicode, (int)wchars); - - return make_utf8_string(unicode); -} - - -// Returns 0 on error, 1 on success -int __stdcall utf8_decode_codepage(const char *from, char **to, WORD wCp) -{ - int nResult = 0; - - _ASSERTE(!(*to)); // You passed a non-zero pointer, make sure it doesnt point to unfreed memory - - // Validate the string - if (!UTF8_IsValid(from)) - return 0; - - // Use the native conversion routines when available - if (bHasCP_UTF8) { - size_t inlen = mir_strlen(from) + 1; - WCHAR *wszTemp = (WCHAR *)_alloca(inlen * sizeof(WCHAR)); - memset(wszTemp, 0, (inlen * sizeof(WCHAR))); - - // Convert the UTF-8 string to UCS - if (MultiByteToWideChar(CP_UTF8, 0, from, -1, wszTemp, (int)inlen)) { - // Convert the UCS string to local ANSI codepage - *to = (char*)SAFE_MALLOC(inlen); - if (WideCharToMultiByte(wCp, 0, wszTemp, -1, *to, (int)inlen, nullptr, nullptr)) { - nResult = 1; - } - else { - SAFE_FREE(to); - } - } - } - else { - size_t chars = mir_strlen(from) + 1; - WCHAR *unicode = (WCHAR*)_alloca(chars * sizeof(WCHAR)); - make_unicode_string_static(from, unicode, chars); - - chars = WideCharToMultiByte(wCp, WC_COMPOSITECHECK, unicode, -1, nullptr, 0, nullptr, nullptr); - - if (chars == 0) { -#ifdef _DEBUG - fprintf(stderr, "Unicode translation error %d\n", GetLastError()); -#endif - return 0; - } - - *to = (char*)SAFE_MALLOC((chars + 1) * sizeof(char)); - if (*to == nullptr) { -#ifdef _DEBUG - fprintf(stderr, "Out of memory processing string to local charset\n"); -#endif - return 0; - } - - int err = WideCharToMultiByte(wCp, WC_COMPOSITECHECK, unicode, -1, *to, (int)chars, nullptr, nullptr); - if (err != (int)chars) { -#ifdef _DEBUG - fprintf(stderr, "Unicode translation error %d\n", GetLastError()); -#endif - SAFE_FREE(to); - return 0; - } - - nResult = 1; - } - - return nResult; -} - - -// Standard version with current codepage -int __stdcall utf8_decode(const char *from, char **to) -{ - return utf8_decode_codepage(from, to, CP_ACP); -} - - -// Returns 0 on error, 1 on success -int __stdcall utf8_decode_static(const char *from, char *to, size_t to_size) -{ - int nResult = 0; - - _ASSERTE(to); // You passed a zero pointer - - // Validate the string - if (!UTF8_IsValid(from)) - return 0; - - // Clear target - memset(to, 0, to_size); - - // Use the native conversion routines when available - if (bHasCP_UTF8) { - size_t inlen = mir_strlen(from) + 1; - WCHAR *wszTemp = (WCHAR*)_alloca(inlen * sizeof(WCHAR)); - memset(wszTemp, 0, (inlen * sizeof(WCHAR))); - - // Convert the UTF-8 string to UCS - if (MultiByteToWideChar(CP_UTF8, 0, from, -1, wszTemp, (int)inlen)) { - // Convert the UCS string to local ANSI codepage - if (WideCharToMultiByte(CP_ACP, 0, wszTemp, -1, to, (int)to_size, nullptr, nullptr)) { - nResult = 1; - } - } - } - else { - size_t chars = mir_strlen(from) + 1; - WCHAR *unicode = (WCHAR*)_alloca(chars * sizeof(WCHAR)); - - make_unicode_string_static(from, unicode, chars); - - WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, unicode, -1, to, (int)to_size, nullptr, nullptr); - - nResult = 1; - } - - return nResult; -} - - -WCHAR* __stdcall ansi_to_unicode(const char *ansi) -{ - int wchars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, ansi, (int)mir_strlen(ansi), nullptr, 0); - - if (wchars == 0) { -#ifdef _DEBUG - fprintf(stderr, "Unicode translation error %d\n", GetLastError()); -#endif - return nullptr; - } - - WCHAR *unicode = (WCHAR*)SAFE_MALLOC((wchars + 1) * sizeof(WCHAR)); - - int err = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, ansi, (int)mir_strlen(ansi), unicode, wchars); - if (err != wchars) { -#ifdef _DEBUG - fprintf(stderr, "Unicode translation error %d\n", GetLastError()); -#endif - SAFE_FREE(&unicode); - return nullptr; - } - return unicode; -} - - -char* __stdcall unicode_to_ansi_static(const WCHAR *unicode, char *ansi, size_t ansi_size) -{ - memset(ansi, 0, ansi_size); - - if (WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, unicode, (int)mir_wstrlen(unicode), ansi, (int)ansi_size, nullptr, nullptr) > 1) - return ansi; - - return nullptr; -} - -char* __stdcall unicode_to_ansi(const WCHAR *unicode) -{ - int chars = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, unicode, (int)mir_wstrlen(unicode), nullptr, 0, nullptr, nullptr); - - if (chars == 0) { -#ifdef _DEBUG - fprintf(stderr, "Unicode translation error %d\n", GetLastError()); -#endif - return nullptr; - } - - char* ansi = (char*)SAFE_MALLOC((chars + 1) * sizeof(char)); - if (ansi == nullptr) { -#ifdef _DEBUG - fprintf(stderr, "Out of memory processing string to local charset\n"); -#endif - return nullptr; - } - - int err = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, unicode, (int)mir_wstrlen(unicode), ansi, chars, nullptr, nullptr); - if (err != chars) { -#ifdef _DEBUG - fprintf(stderr, "Unicode translation error %d\n", GetLastError()); -#endif - return nullptr; - } - - return ansi; -} diff --git a/protocols/IcqOscarJ/src/i18n.h b/protocols/IcqOscarJ/src/i18n.h deleted file mode 100644 index 5e1ebb1156..0000000000 --- a/protocols/IcqOscarJ/src/i18n.h +++ /dev/null @@ -1,61 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// Helper functions to convert text messages between different character sets. -// ----------------------------------------------------------------------------- - -#ifndef __I18N_H -#define __I18N_H - -BOOL CALLBACK IsUSASCII(const char *pBuffer, size_t nSize); -BOOL CALLBACK IsUnicodeAscii(const WCHAR *pBuffer, size_t nSize); -int CALLBACK UTF8_IsValid(const char *pszInput); - -int CALLBACK get_utf8_size(const WCHAR *unicode); - -char* CALLBACK detect_decode_utf8(const char *from); - -WCHAR* CALLBACK make_unicode_string(const char *utf8); -WCHAR* CALLBACK make_unicode_string_static(const char *utf8, WCHAR *unicode, size_t unicode_size); - -char* CALLBACK make_utf8_string(const WCHAR *unicode); -char* CALLBACK make_utf8_string_static(const WCHAR *unicode, char *utf8, size_t utf_size); - -char* CALLBACK ansi_to_utf8(const char *ansi); -char* CALLBACK ansi_to_utf8_codepage(const char *ansi, WORD wCp); - -WCHAR* CALLBACK ansi_to_unicode(const char *ansi); -char* CALLBACK unicode_to_ansi(const WCHAR *unicode); -char* CALLBACK unicode_to_ansi_static(const WCHAR *unicode, char *ansi, size_t ansi_size); - -int CALLBACK utf8_encode(const char *from, char **to); -int CALLBACK utf8_decode(const char *from, char **to); -int CALLBACK utf8_decode_codepage(const char *from, char **to, WORD wCp); -int CALLBACK utf8_decode_static(const char *from, char *to, size_t to_size); - -void InitI18N(void); - -#endif /* __I18N_H */ diff --git a/protocols/IcqOscarJ/src/icq_advsearch.cpp b/protocols/IcqOscarJ/src/icq_advsearch.cpp deleted file mode 100644 index 552efc5798..0000000000 --- a/protocols/IcqOscarJ/src/icq_advsearch.cpp +++ /dev/null @@ -1,149 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2008 Joe Kucera, Bio -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -static void InitComboBox(HWND hwndCombo, const FieldNamesItem *names) -{ - SendMessage(hwndCombo, CB_SETCURSEL, ComboBoxAddStringUtf(hwndCombo, nullptr, 0), 0); - - if (names) { - for (int i = 0; names[i].text; i++) - ComboBoxAddStringUtf(hwndCombo, names[i].text, names[i].code); - } - else { - int ctryCount; - struct CountryListEntry *countries; - CallService(MS_UTILS_GETCOUNTRYLIST, (WPARAM)&ctryCount, (LPARAM)&countries); - for (int i = 0; i < ctryCount; i++) - if (countries[i].id != 0xFFFF && countries[i].id != 0) - ComboBoxAddStringUtf(hwndCombo, LPGEN(countries[i].szName), countries[i].id); - } -} - -INT_PTR CALLBACK AdvancedSearchDlgProc(HWND hwndDlg, UINT message, WPARAM, LPARAM) -{ - switch (message) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - InitComboBox(GetDlgItem(hwndDlg, IDC_GENDER), genderField); - InitComboBox(GetDlgItem(hwndDlg, IDC_AGERANGE), agesField); - InitComboBox(GetDlgItem(hwndDlg, IDC_MARITALSTATUS), maritalField); - InitComboBox(GetDlgItem(hwndDlg, IDC_WORKFIELD), occupationField); - InitComboBox(GetDlgItem(hwndDlg, IDC_ORGANISATION), affiliationField); - InitComboBox(GetDlgItem(hwndDlg, IDC_LANGUAGE), languageField); - InitComboBox(GetDlgItem(hwndDlg, IDC_COUNTRY), countryField); - InitComboBox(GetDlgItem(hwndDlg, IDC_INTERESTSCAT), interestsField); - InitComboBox(GetDlgItem(hwndDlg, IDC_PASTCAT), pastField); - return TRUE; - } - - return FALSE; -} - -static DWORD getCurItemData(HWND hwndDlg, UINT iCtrl) -{ - return SendDlgItemMessage(hwndDlg, iCtrl, CB_GETITEMDATA, SendDlgItemMessage(hwndDlg, iCtrl, CB_GETCURSEL, 0, 0), 0); -} - -static void searchPackTLVLNTS(PBYTE *buf, size_t *buflen, HWND hwndDlg, UINT idControl, WORD wType) -{ - char str[512]; - - GetDlgItemTextA(hwndDlg, idControl, str, _countof(str)); - - ppackLETLVLNTS(buf, buflen, str, wType, 0); -} - -static void searchPackTLVWordLNTS(PBYTE *buf, size_t *buflen, HWND hwndDlg, UINT idControl, WORD w, WORD wType) -{ - char str[512]; - - GetDlgItemTextA(hwndDlg, idControl, str, _countof(str)); - - ppackLETLVWordLNTS(buf, buflen, w, str, wType, 0); -} - -static PBYTE createAdvancedSearchStructureTLV(HWND hwndDlg, size_t *length) -{ - PBYTE buf = nullptr; - size_t buflen = 0; - - ppackLEWord(&buf, &buflen, META_SEARCH_GENERIC); /* subtype: full search */ - - searchPackTLVLNTS(&buf, &buflen, hwndDlg, IDC_FIRSTNAME, TLV_FIRSTNAME); - searchPackTLVLNTS(&buf, &buflen, hwndDlg, IDC_LASTNAME, TLV_LASTNAME); - searchPackTLVLNTS(&buf, &buflen, hwndDlg, IDC_NICK, TLV_NICKNAME); - searchPackTLVLNTS(&buf, &buflen, hwndDlg, IDC_EMAIL, TLV_EMAIL); - searchPackTLVLNTS(&buf, &buflen, hwndDlg, IDC_CITY, TLV_CITY); - searchPackTLVLNTS(&buf, &buflen, hwndDlg, IDC_STATE, TLV_STATE); - searchPackTLVLNTS(&buf, &buflen, hwndDlg, IDC_COMPANY, TLV_COMPANY); - searchPackTLVLNTS(&buf, &buflen, hwndDlg, IDC_DEPARTMENT, TLV_DEPARTMENT); - searchPackTLVLNTS(&buf, &buflen, hwndDlg, IDC_POSITION, TLV_POSITION); - searchPackTLVLNTS(&buf, &buflen, hwndDlg, IDC_KEYWORDS, TLV_KEYWORDS); - - ppackLETLVDWord(&buf, &buflen, (DWORD)getCurItemData(hwndDlg, IDC_AGERANGE), TLV_AGERANGE, 0); - - BYTE b = (BYTE)getCurItemData(hwndDlg, IDC_GENDER); - switch (b) { - case 'F': b = 1; break; - case 'M': b = 2; break; - default: b = 0; - } - ppackLETLVByte(&buf, &buflen, b, TLV_GENDER, 0); - ppackLETLVByte(&buf, &buflen, (BYTE)getCurItemData(hwndDlg, IDC_MARITALSTATUS), TLV_MARITAL, 0); - ppackLETLVWord(&buf, &buflen, (WORD)getCurItemData(hwndDlg, IDC_LANGUAGE), TLV_LANGUAGE, 0); - ppackLETLVWord(&buf, &buflen, (WORD)getCurItemData(hwndDlg, IDC_COUNTRY), TLV_COUNTRY, 0); - ppackLETLVWord(&buf, &buflen, (WORD)getCurItemData(hwndDlg, IDC_WORKFIELD), TLV_OCUPATION, 0); - - WORD w = (WORD)getCurItemData(hwndDlg, IDC_PASTCAT); - searchPackTLVWordLNTS(&buf, &buflen, hwndDlg, IDC_PASTKEY, w, TLV_PASTINFO); - - w = (WORD)getCurItemData(hwndDlg, IDC_INTERESTSCAT); - searchPackTLVWordLNTS(&buf, &buflen, hwndDlg, IDC_INTERESTSKEY, w, TLV_INTERESTS); - - w = (WORD)getCurItemData(hwndDlg, IDC_ORGANISATION); - searchPackTLVWordLNTS(&buf, &buflen, hwndDlg, IDC_ORGKEYWORDS, w, TLV_AFFILATIONS); - - w = (WORD)getCurItemData(hwndDlg, IDC_HOMEPAGECAT); - if (w != 0xFFFF) - searchPackTLVWordLNTS(&buf, &buflen, hwndDlg, IDC_HOMEPAGEKEY, w, TLV_HOMEPAGE); - - if (IsDlgButtonChecked(hwndDlg, IDC_ONLINEONLY)) - ppackLETLVByte(&buf, &buflen, 1, TLV_ONLINEONLY, 1); - - if (length) - *length = buflen; - - return buf; -} - -PBYTE createAdvancedSearchStructure(HWND hwndDlg, size_t *length) -{ - if (!hwndDlg) - return nullptr; - - return createAdvancedSearchStructureTLV(hwndDlg, length); -} diff --git a/protocols/IcqOscarJ/src/icq_advsearch.h b/protocols/IcqOscarJ/src/icq_advsearch.h deleted file mode 100644 index d04e8b8e31..0000000000 --- a/protocols/IcqOscarJ/src/icq_advsearch.h +++ /dev/null @@ -1,28 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000,2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001,2002 Jon Keating, Richard Hughes -// Copyright © 2002,2003,2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// ----------------------------------------------------------------------------- - -#pragma once - -INT_PTR CALLBACK AdvancedSearchDlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam); -PBYTE createAdvancedSearchStructure(HWND hwndDlg, size_t *length); diff --git a/protocols/IcqOscarJ/src/icq_avatar.cpp b/protocols/IcqOscarJ/src/icq_avatar.cpp deleted file mode 100644 index eb747258d0..0000000000 --- a/protocols/IcqOscarJ/src/icq_avatar.cpp +++ /dev/null @@ -1,1315 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// Manages Avatar connection, provides internal service for handling avatars -// ----------------------------------------------------------------------------- - -#include "stdafx.h" -#include "m_folders.h" - -BYTE hashEmptyAvatar[9] = { 0x00, 0x01, 0x00, 0x05, 0x02, 0x01, 0xD2, 0x04, 0x72 }; - -avatars_request::avatars_request(int type) -{ - this->type = type; -} - -avatars_request::~avatars_request() -{ - if (this) { - switch (type) { - case ART_UPLOAD: - SAFE_FREE((void**)&pData); - break; - case ART_GET: - SAFE_FREE((void**)&hash); - SAFE_FREE(&szFile); - break; - case ART_BLOCK: - break; - } - } -} - -wchar_t* CIcqProto::GetOwnAvatarFileName() -{ - DBVARIANT dbvFile = { DBVT_DELETED }; - if (getWString(NULL, "AvatarFile", &dbvFile)) - return nullptr; - - wchar_t tmp[MAX_PATH * 2]; - PathToAbsoluteW(dbvFile.pwszVal, tmp); - db_free(&dbvFile); - - return null_strdup(tmp); -} - -void CIcqProto::GetFullAvatarFileName(int dwUin, const char *szUid, int dwFormat, wchar_t *pszDest, size_t cbLen) -{ - GetAvatarFileName(dwUin, szUid, pszDest, cbLen); - AddAvatarExt(dwFormat, pszDest); -} - -void CIcqProto::GetAvatarFileName(int dwUin, const char *szUid, wchar_t *pszDest, size_t cbLen) -{ - wchar_t szPath[MAX_PATH * 2]; - mir_snwprintf(szPath, L"%s\\%S\\", VARSW(L"%miranda_avatarcache%"), m_szModuleName); - - FOLDERSGETDATA fgd = { sizeof(fgd) }; - fgd.nMaxPathSize = _countof(szPath); - fgd.szPathT = szPath; - fgd.flags = FF_TCHAR; - - // fill the destination - mir_wstrncpy(pszDest, szPath, cbLen - 1); - size_t tPathLen = mir_wstrlen(pszDest); - - // make sure the avatar cache directory exists - CreateDirectoryTreeW(szPath); - - if (dwUin != 0) - _ltow(dwUin, pszDest + tPathLen, 10); - else if (szUid) { - wchar_t* p = mir_a2u(szUid); - mir_wstrcpy(pszDest + tPathLen, p); - mir_free(p); - } - else { - wchar_t szBuf[MAX_PATH]; - if (Profile_GetNameW(MAX_PATH, szBuf)) - mir_wstrcpy(pszDest + tPathLen, L"avatar"); - else { - wchar_t *szLastDot = wcsrchr(szBuf, '.'); - if (szLastDot) - szLastDot[0] = '\0'; - - mir_wstrcpy(pszDest + tPathLen, szBuf); - mir_wstrcat(pszDest + tPathLen, L"_avt"); - } - } -} - -void AddAvatarExt(int dwFormat, wchar_t *pszDest) -{ - const wchar_t *ext = ProtoGetAvatarExtension(dwFormat); - mir_wstrcat(pszDest, (*ext == 0) ? L".dat" : ext); -} - -#define MD5_BLOCK_SIZE 1024*1024 /* use 1MB blocks */ - -BYTE* calcMD5HashOfFile(const wchar_t *tszFile) -{ - BYTE *res = nullptr; - - HANDLE hFile = nullptr, hMap = nullptr; - if ((hFile = CreateFile(tszFile, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr)) != INVALID_HANDLE_VALUE) { - if ((hMap = CreateFileMapping(hFile, nullptr, PAGE_READONLY, 0, 0, nullptr)) != nullptr) { - long cbFileSize = GetFileSize(hFile, nullptr); - - res = (BYTE*)SAFE_MALLOC(16 * sizeof(BYTE)); - if (cbFileSize != 0 && res) { - mir_md5_state_t state; - BYTE digest[16]; - int dwOffset = 0; - - mir_md5_init(&state); - while (dwOffset < cbFileSize) { - BYTE *ppMap = nullptr; - int dwBlockSize = min(MD5_BLOCK_SIZE, cbFileSize - dwOffset); - if (!(ppMap = (BYTE*)MapViewOfFile(hMap, FILE_MAP_READ, 0, dwOffset, dwBlockSize))) - break; - - mir_md5_append(&state, (const BYTE *)ppMap, dwBlockSize); - UnmapViewOfFile(ppMap); - dwOffset += dwBlockSize; - } - mir_md5_finish(&state, digest); - memcpy(res, digest, 16 * sizeof(BYTE)); - } - } - - if (hMap != nullptr) CloseHandle(hMap); - if (hFile != nullptr) CloseHandle(hFile); - } - - return res; -} - -int CIcqProto::IsAvatarChanged(MCONTACT hContact, const BYTE *pHash, size_t nHashLen) -{ - DBVARIANT dbvSaved = { 0 }; - if (getSetting(hContact, "AvatarSaved", &dbvSaved)) - return 1; // saved Avatar hash is missing - - // are the hashes different? - int ret = (dbvSaved.cpbVal != nHashLen || memcmp(dbvSaved.pbVal, pHash, nHashLen)) ? 2 : 0; - db_free(&dbvSaved); - return ret; -} - -void CIcqProto::StartAvatarThread(HNETLIBCONN hConn, char *cookie, size_t cookieLen) // called from event -{ - if (!hConn) { - mir_cslock l(m_avatarsMutex); // place avatars lock - - if (m_avatarsConnection && m_avatarsConnection->isPending()) { - debugLogA("Avatar, Multiple start thread attempt, ignored."); - SAFE_FREE((void**)&cookie); - return; - } - debugLogA("Avatars: Connection failed"); - - m_avatarsConnectionPending = FALSE; - - // check if any upload request are waiting in the queue - int bYet = 0; - - auto T = m_arAvatars.rev_iter(); - for (auto &it : T) { - if (it->type == ART_UPLOAD) { // we found it, return error - if (!bYet) { - icq_LogMessage(LOG_WARNING, LPGEN("Error uploading avatar to server, server temporarily unavailable.")); - bYet = 1; - } - - // remove upload request from queue - delete it; - m_arAvatars.remove(T.indexOf(&it)); - } - } - - SAFE_FREE((void**)&cookie); - return; - } - - mir_cslock l(m_avatarsMutex); - - if (m_avatarsConnection && m_avatarsConnection->isPending()) { - debugLogA("Avatar, Multiple start thread attempt, ignored."); - - NetLib_CloseConnection(&hConn, false); - - SAFE_FREE((void**)&cookie); - return; - } - - if (m_avatarsConnection) - m_avatarsConnection->closeConnection(); - m_avatarsConnection = new avatars_server_connection(this, hConn, cookie, cookieLen); // the old connection should not be used anymore - - // connection object created, remove the connection request pending flag - m_avatarsConnectionPending = false; -} - -void CIcqProto::StopAvatarThread() -{ - mir_cslock l(m_avatarsMutex); // the connection is about to close - if (m_avatarsConnection) - m_avatarsConnection->shutdownConnection(); // make the thread stop -} - -// handle Owner's avatar hash changes -void CIcqProto::handleAvatarOwnerHash(BYTE bFlags, BYTE *pData, size_t nDataLen) -{ - if (nDataLen < 0x14 || !m_bAvatarsEnabled) - return; - - switch (bFlags) { - case 1: // our avatar is on the server - setSettingBlob(NULL, "AvatarHash", pData, 0x14); /// TODO: properly handle multiple avatar items (more formats) - setUserInfo(); - { - // here we need to find a file, check its hash, if invalid get avatar from server - wchar_t *file = GetOwnAvatarFileName(); - if (!file) { // we have no avatar file, download from server - debugLogA("We have no avatar, requesting from server."); - - wchar_t szFile[MAX_PATH * 2 + 4]; - GetAvatarFileName(0, nullptr, szFile, MAX_PATH * 2); - GetAvatarData(NULL, m_dwLocalUIN, nullptr, pData, 0x14, szFile); - } - else { // we know avatar filename - BYTE *hash = calcMD5HashOfFile(file); - - if (!hash) { // hash could not be calculated - probably missing file, get avatar from server - debugLogA("We have no avatar, requesting from server."); - - wchar_t szFile[MAX_PATH * 2 + 4]; - GetAvatarFileName(0, nullptr, szFile, MAX_PATH * 2); - GetAvatarData(NULL, m_dwLocalUIN, nullptr, pData, 0x14, szFile); - } - // check if we had set any avatar if yes set our, if not download from server - else if (memcmp(hash, pData + 4, 0x10)) { // we have different avatar, sync that - if (m_bSsiEnabled && getByte("ForceOurAvatar", 1)) { // we want our avatar, update hash - DWORD dwPaFormat = ::ProtoGetAvatarFileFormat(file); - BYTE pHash[0x14]; - - debugLogA("Our avatar is different, setting our new hash."); - - pHash[0] = 0; - pHash[1] = dwPaFormat == PA_FORMAT_XML ? AVATAR_HASH_FLASH : AVATAR_HASH_STATIC; - pHash[2] = 1; // state of the hash - pHash[3] = 0x10; // len of the hash - memcpy((pHash + 4), hash, 0x10); - updateServAvatarHash(pHash, 0x14); - } - else { // get avatar from server - debugLogA("We have different avatar, requesting new from server."); - - wchar_t tszFile[MAX_PATH * 2 + 4]; - GetAvatarFileName(0, nullptr, tszFile, MAX_PATH * 2); - GetAvatarData(NULL, m_dwLocalUIN, nullptr, pData, 0x14, tszFile); - } - } - SAFE_FREE((void**)&hash); - SAFE_FREE(&file); - } - } - break; - - case 0x41: // request to upload avatar data - case 0x81: - // request to re-upload avatar data - if (m_bSsiEnabled) { // we could not change serv-list if it is disabled... - wchar_t *file = GetOwnAvatarFileName(); - if (!file) { // we have no file to upload, remove hash from server - debugLogA("We do not have avatar, removing hash."); - SetMyAvatar(0, 0); - break; - } - - DWORD dwPaFormat = ::ProtoGetAvatarFileFormat(file); - BYTE *hash = calcMD5HashOfFile(file); - if (!hash) { // the hash could not be calculated, remove from server - debugLogA("We could not obtain hash, removing hash."); - SetMyAvatar(0, 0); - } - else if (!memcmp(hash, pData + 4, 0x10)) { // we have the right file - HANDLE hFile = nullptr, hMap = nullptr; - BYTE *ppMap = nullptr; - long cbFileSize = 0; - - debugLogA("Uploading our avatar data."); - - if ((hFile = CreateFile(file, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr)) != INVALID_HANDLE_VALUE) - if ((hMap = CreateFileMapping(hFile, nullptr, PAGE_READONLY, 0, 0, nullptr)) != nullptr) - if ((ppMap = (BYTE*)MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) != nullptr) - cbFileSize = GetFileSize(hFile, nullptr); - - if (cbFileSize != 0) - SetAvatarData(NULL, (WORD)(dwPaFormat == PA_FORMAT_XML ? AVATAR_HASH_FLASH : AVATAR_HASH_STATIC), ppMap, cbFileSize); - - if (ppMap != nullptr) UnmapViewOfFile(ppMap); - if (hMap != nullptr) CloseHandle(hMap); - if (hFile != nullptr) CloseHandle(hFile); - SAFE_FREE((void**)&hash); - } - else { - BYTE pHash[0x14]; - - debugLogA("Our file is different, set our new hash."); - - pHash[0] = 0; - pHash[1] = dwPaFormat == PA_FORMAT_XML ? AVATAR_HASH_FLASH : AVATAR_HASH_STATIC; - pHash[2] = 1; // state of the hash - pHash[3] = 0x10; // len of the hash - memcpy((pHash + 4), hash, 0x10); - updateServAvatarHash(pHash, 0x14); - - SAFE_FREE((void**)&hash); - } - - SAFE_FREE(&file); - } - break; - - default: - debugLogA("Received UNKNOWN Avatar Status."); - } -} - -// handle Contact's avatar hash -void CIcqProto::handleAvatarContactHash(DWORD dwUIN, char *szUID, MCONTACT hContact, BYTE *pHash, size_t nHashLen) -{ - int bJob = FALSE; - BOOL avatarInfoPresent = FALSE; - int avatarType = -1; - BYTE *pAvatarHash = nullptr; - size_t cbAvatarHash = 0; - BYTE emptyItem[0x10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - - if (!m_bAvatarsEnabled || nHashLen < 4) - return; // only if enabled - - while (nHashLen >= 4) { // parse online message items one by one - WORD itemType = pHash[0] << 8 | pHash[1]; - size_t itemLen = pHash[3]; - - // just some validity check - if (itemLen + 4 > nHashLen) - itemLen = nHashLen - 4; - - if (itemLen && memcmp(pHash + 4, emptyItem, itemLen > 0x10 ? 0x10 : itemLen)) { - // Item types - // 0000: AIM mini avatar - // 0001: AIM/ICQ avatar ID/hash (len 5 or 16 bytes) - // 0002: iChat online message - // 0008: ICQ Flash avatar hash (16 bytes) - // 0009: iTunes music store link - // 000C: ICQ contact photo (16 bytes) - // 000D: Last update time of online message - // 000E: Status mood - if (itemType == AVATAR_HASH_MINI && itemLen == 0x05 && avatarType == -1) { // mini avatar - pAvatarHash = pHash; - cbAvatarHash = itemLen + 4; - avatarType = itemType; - } - else if (itemType == AVATAR_HASH_STATIC && (itemLen == 0x05 || itemLen == 0x10) && (avatarType == -1 || avatarType == AVATAR_HASH_MINI)) { // normal avatar - pAvatarHash = pHash; - cbAvatarHash = itemLen + 4; - avatarType = itemType; - } - else if (itemType == AVATAR_HASH_FLASH && itemLen == 0x10 && (avatarType == -1 || avatarType == AVATAR_HASH_MINI || avatarType == AVATAR_HASH_STATIC)) { // flash avatar - pAvatarHash = pHash; - cbAvatarHash = itemLen + 4; - avatarType = itemType; - } - else if (itemType == AVATAR_HASH_PHOTO && itemLen == 0x10) { // big avatar (ICQ 6+) - pAvatarHash = pHash; - cbAvatarHash = itemLen + 4; - avatarType = itemType; - } - } - else if ((itemLen == 0) && (itemType == AVATAR_HASH_MINI || itemType == AVATAR_HASH_STATIC || itemType == AVATAR_HASH_FLASH || itemType == AVATAR_HASH_PHOTO)) - // empty item - indicating that avatar of that type was removed - avatarInfoPresent = TRUE; - - pHash += itemLen + 4; - nHashLen -= itemLen + 4; - } - - if (avatarType != -1) { // check settings, should we request avatar immediatelly? - DBVARIANT dbv = { DBVT_DELETED }; - wchar_t tszAvatar[MAX_PATH * 2 + 4]; - BYTE bAutoLoad = getByte("AvatarsAutoLoad", DEFAULT_LOAD_AVATARS); - - if ((avatarType == AVATAR_HASH_STATIC || avatarType == AVATAR_HASH_MINI) && cbAvatarHash == 0x09 && !memcmp(pAvatarHash + 4, hashEmptyAvatar + 4, 0x05)) { // empty avatar - unlink image, clear hash - if (!getSetting(hContact, "AvatarHash", &dbv)) { // contact had avatar, clear hash, notify UI - db_free(&dbv); - debugLogA("%s has removed Avatar.", strUID(dwUIN, szUID)); - - delSetting(hContact, "AvatarHash"); - ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_STATUS, nullptr, 0); - } - else debugLogA("%s has empty Avatar.", strUID(dwUIN, szUID)); - return; - } - - if (getSetting(hContact, "AvatarHash", &dbv)) { // we did not find old avatar hash, i.e. get new avatar - int avatarState = IsAvatarChanged(hContact, pAvatarHash, cbAvatarHash); - - // check saved hash and file, if equal only store hash - if (!avatarState) { // hashes are the same - int dwPaFormat = getByte(hContact, "AvatarType", PA_FORMAT_UNKNOWN); - - GetFullAvatarFileName(dwUIN, szUID, dwPaFormat, tszAvatar, MAX_PATH * 2); - if (_waccess(tszAvatar, 0) == 0) { // the file is there, link to contactphoto, save hash - debugLogA("%s has published Avatar. Image was found in the cache.", strUID(dwUIN, szUID)); - - setSettingBlob(hContact, "AvatarHash", pAvatarHash, cbAvatarHash); - ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_STATUS, nullptr, 0); - } - else { // the file was lost, request avatar again - debugLogA("%s has published Avatar.", strUID(dwUIN, szUID)); - bJob = TRUE; - } - } - else { // the hash is not the one we want, request avatar - debugLogA("%s has published a new Avatar.", strUID(dwUIN, szUID)); - bJob = TRUE; - } - } - else { // we found hash check if it changed or not - if ((dbv.cpbVal != cbAvatarHash) || memcmp(dbv.pbVal, pAvatarHash, cbAvatarHash)) { // the hash is different, request new avatar - debugLogA("%s has changed Avatar.", strUID(dwUIN, szUID)); - bJob = TRUE; - } - else { // the hash was not changed, check if we have the correct file - int avatarState = IsAvatarChanged(hContact, pAvatarHash, cbAvatarHash); - - // we should have file, check if the file really exists - if (!avatarState) { - int dwPaFormat = getByte(hContact, "AvatarType", PA_FORMAT_UNKNOWN); - if (dwPaFormat == PA_FORMAT_UNKNOWN) { // we do not know the format, get avatar again - debugLogA("%s has Avatar. Image is missing.", strUID(dwUIN, szUID)); - bJob = 2; - } - else { - GetFullAvatarFileName(dwUIN, szUID, dwPaFormat, tszAvatar, MAX_PATH * 2); - if (_waccess(tszAvatar, 0) != 0) { // the file was lost, get it again - debugLogA("%s has Avatar. Image is missing.", strUID(dwUIN, szUID)); - bJob = 2; - } - else debugLogA("%s has Avatar. Image was found in the cache.", strUID(dwUIN, szUID)); - } - } - else { // the hash is not the one we want, request avatar - debugLogA("%s has Avatar. Image was not retrieved yet.", strUID(dwUIN, szUID)); - bJob = 2; - } - } - db_free(&dbv); - } - - if (bJob) { - if (bJob == TRUE) { // Remove possible block - hash changed, try again. - mir_cslock l(m_avatarsMutex); - - for (auto &it : m_arAvatars) { - if (it->hContact == hContact && it->type == ART_BLOCK) { // found one, remove - delete it; - m_arAvatars.removeItem(&it); - break; - } - } - } - - setSettingBlob(hContact, "AvatarHash", pAvatarHash, cbAvatarHash); - - ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_STATUS, nullptr, 0); - - if (bAutoLoad) { // auto-load is on, so request the avatar now, otherwise we are done - GetAvatarFileName(dwUIN, szUID, tszAvatar, MAX_PATH * 2); - GetAvatarData(hContact, dwUIN, szUID, pAvatarHash, cbAvatarHash, tszAvatar); - } // avatar request sent or added to queue - } - } - else if (avatarInfoPresent) { // hash was not found, clear the hash - DBVARIANT dbv = { DBVT_DELETED }; - if (!getSetting(hContact, "AvatarHash", &dbv)) { // contact had avatar, clear hash, notify UI - db_free(&dbv); - debugLogA("%s has removed Avatar.", strUID(dwUIN, szUID)); - - delSetting(hContact, "AvatarHash"); - ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_STATUS, nullptr, 0); - } - else debugLogA("%s has no Avatar.", strUID(dwUIN, szUID)); - } -} - -// request avatar data from server -int CIcqProto::GetAvatarData(MCONTACT hContact, DWORD dwUin, const char *szUid, const BYTE *hash, size_t hashlen, const wchar_t *file) -{ - uid_str szUidData; - char *pszUid = nullptr; - if (!dwUin && szUid) { // create a copy in local writable buffer - mir_strcpy(szUidData, szUid); - pszUid = szUidData; - } - - mir_cslockfull alck(m_avatarsMutex); - - if (m_avatarsConnection && m_avatarsConnection->isReady()) { // check if we are ready - // check if requests for this user are not blocked - auto T = m_arAvatars.rev_iter(); - for (auto &ar : T) { - if (ar->hContact == hContact && ar->type == ART_BLOCK) { // found a block item - if (GetTickCount() > ar->timeOut) { // remove timeouted block - delete ar; - m_arAvatars.remove(T.indexOf(&ar)); - continue; - } - debugLogA("Avatars: Requests for %s avatar are blocked.", strUID(dwUin, pszUid)); - return 0; - } - } - - mir_cslock l(m_avatarsConnection->getLock()); - alck.unlock(); - - DWORD dwCookie = m_avatarsConnection->sendGetAvatarRequest(hContact, dwUin, pszUid, hash, hashlen, file); - if (dwCookie) // return now if the request was sent successfully - return dwCookie; - - alck.lock(); - } - // we failed to send request, or avatar thread not ready - - // check if any request for this user is not already in the queue - auto T = m_arAvatars.rev_iter(); - for (auto &ar : T) { - if (ar->hContact == hContact) { // we found it, return error - if (ar->type == ART_BLOCK && GetTickCount() > ar->timeOut) { // remove timeouted block - delete ar; - m_arAvatars.remove(T.indexOf(&ar)); - continue; - } - alck.unlock(); - debugLogA("Avatars: Ignoring duplicate get %s avatar request.", strUID(dwUin, pszUid)); - - // make sure avatar connection is in progress - requestAvatarConnection(); - return 0; - } - } - - // add request to queue, processed after successful login - avatars_request *ar = new avatars_request(ART_GET); // get avatar - ar->hContact = hContact; - ar->dwUin = dwUin; - if (!dwUin) - mir_strcpy(ar->szUid, szUid); - ar->hash = (BYTE*)SAFE_MALLOC(hashlen); - if (!ar->hash) { // alloc failed - delete ar; - return 0; - } - memcpy(ar->hash, hash, hashlen); // copy the data - ar->hashlen = hashlen; - ar->szFile = null_strdup(file); // duplicate the string - m_arAvatars.insert(ar); - alck.unlock(); - - debugLogA("Avatars: Request to get %s image added to queue.", strUID(dwUin, pszUid)); - - // make sure avatar connection is in progress - requestAvatarConnection(); - return -1; // we added to queue -} - -// upload avatar data to server -int CIcqProto::SetAvatarData(MCONTACT hContact, WORD wRef, const BYTE *data, size_t datalen) -{ - mir_cslockfull alck(m_avatarsMutex); - - if (m_avatarsConnection && m_avatarsConnection->isReady()) { // check if we are ready - mir_cslock l(m_avatarsConnection->getLock()); - alck.unlock(); - - DWORD dwCookie = m_avatarsConnection->sendUploadAvatarRequest(hContact, wRef, data, datalen); - if (dwCookie) // return now if the request was sent successfully - return dwCookie; - - alck.lock(); - } - // we failed to send request, or avatar thread not ready - - // check if any request for this user is not already in the queue - for (auto ar : m_arAvatars) { - if (ar->hContact == hContact && ar->type == ART_UPLOAD) { // we found it, return error - alck.unlock(); - debugLogA("Avatars: Ignoring duplicate upload avatar request."); - - // make sure avatar connection is in progress - requestAvatarConnection(); - return 0; - } - } - - // add request to queue, processed after successful login - avatars_request *ar = new avatars_request(ART_UPLOAD); // upload avatar - ar->hContact = hContact; - ar->pData = (BYTE*)SAFE_MALLOC(datalen); - if (!ar->pData) { // alloc failed - delete ar; - return 0; - } - - memcpy(ar->pData, data, datalen); // copy the data - ar->cbData = datalen; - ar->wRef = wRef; - m_arAvatars.insert(ar); - alck.unlock(); - - debugLogA("Avatars: Request to upload image added to queue."); - - // make sure avatar connection is in progress - requestAvatarConnection(); - return -1; // we added to queue -} - -void CIcqProto::requestAvatarConnection() -{ - mir_cslockfull alck(m_avatarsMutex); - if (!m_avatarsConnectionPending && (!m_avatarsConnection || (!m_avatarsConnection->isPending() && !m_avatarsConnection->isReady()))) { - // avatar connection is not pending, request new one - m_avatarsConnectionPending = TRUE; - alck.unlock(); - - icq_requestnewfamily(ICQ_AVATAR_FAMILY, &CIcqProto::StartAvatarThread); - } -} - -void __cdecl CIcqProto::AvatarThread(avatars_server_connection *pInfo) -{ - debugLogA("%s thread started.", "Avatar"); - Thread_SetName("ICQ: AvatarThread"); - - // Execute connection handler - pInfo->connectionThread(); - { - // Remove connection reference - mir_cslock l(m_avatarsMutex); - if (m_avatarsConnection == pInfo) - m_avatarsConnection = nullptr; - - // Release connection handler - delete pInfo; - } - - debugLogA("%s thread ended.", "Avatar"); -} - -avatars_server_connection::avatars_server_connection(CIcqProto *_ppro, HNETLIBCONN _hConnection, char *_pCookie, size_t _wCookieLen) : - isLoggedIn(false), stopThread(false), isActive(false), - ppro(_ppro), - pCookie(_pCookie), - wCookieLen(_wCookieLen), - hConnection(_hConnection) -{ - // Initialize packet sequence - wLocalSequence = generate_flap_sequence(); - - // Create connection thread - ppro->ForkThread((CIcqProto::MyThreadFunc)&CIcqProto::AvatarThread, this); -} - -avatars_server_connection::~avatars_server_connection() -{ - delete m_rates; -} - -void avatars_server_connection::closeConnection() -{ - stopThread = TRUE; - - mir_cslock l(localSeqMutex); - if (hConnection) { - Netlib_CloseHandle(hConnection); - hConnection = nullptr; - } -} - -void avatars_server_connection::shutdownConnection() -{ - stopThread = TRUE; - - mir_cslock l(localSeqMutex); - if (hConnection) - Netlib_Shutdown(hConnection); -} - -DWORD avatars_server_connection::sendGetAvatarRequest(MCONTACT hContact, DWORD dwUin, char *szUid, const BYTE *hash, size_t hashlen, const wchar_t *file) -{ - DWORD dwNow = GetTickCount(); - - mir_cslockfull alck(ppro->m_avatarsMutex); - - for (int i = 0; i < runCount;) { // look for timeouted requests - if (runTime[i] < dwNow) { // found outdated, remove - runContact[i] = runContact[runCount - 1]; - runTime[i] = runTime[runCount - 1]; - runCount--; - } - else i++; - } - - for (int i = 0; i < runCount; i++) { - if (runContact[i] == hContact) { - ppro->debugLogA("Ignoring duplicate get %s image request.", strUID(dwUin, szUid)); - return -1; // Success: request ignored - } - } - - if (runCount < 4) { // 4 concurent requests at most - int bSendNow = TRUE; - { - // rate management - mir_cslock l(m_ratesMutex); - WORD wGroup = m_rates->getGroupFromSNAC(ICQ_AVATAR_FAMILY, ICQ_AVATAR_GET_REQUEST); - - if (m_rates->getNextRateLevel(wGroup) < m_rates->getLimitLevel(wGroup, RML_ALERT)) { // we will be over quota if we send the request now, add to queue instead - bSendNow = FALSE; - ppro->debugLogA("Rates: Delay avatar request."); - } - } - - if (bSendNow) { - runContact[runCount] = hContact; - runTime[runCount] = GetTickCount() + 30000; // 30sec to complete request - runCount++; - - alck.unlock(); - - int nUinLen = getUIDLen(dwUin, szUid); - - cookie_avatar *ack = (cookie_avatar*)SAFE_MALLOC(sizeof(cookie_avatar)); - if (!ack) - return 0; // Failure: out of memory - - ack->dwUin = 1; //dwUin; // I should be damned for this - only to identify get request - ack->hContact = hContact; - ack->hash = (BYTE*)SAFE_MALLOC(hashlen); - memcpy(ack->hash, hash, hashlen); // copy the data - ack->hashlen = hashlen; - ack->szFile = null_strdup(file); // duplicate the string - - DWORD dwCookie = ppro->AllocateCookie(CKT_AVATAR, ICQ_AVATAR_GET_REQUEST, hContact, ack); - icq_packet packet; - - serverPacketInit(&packet, 12 + nUinLen + hashlen); - packFNACHeader(&packet, ICQ_AVATAR_FAMILY, ICQ_AVATAR_GET_REQUEST, 0, dwCookie); - packUID(&packet, dwUin, szUid); - packByte(&packet, 1); // unknown, probably type of request: 1 = get icon :) - packBuffer(&packet, hash, hashlen); - - if (sendServerPacket(&packet)) { - ppro->debugLogA("Request to get %s image sent.", strUID(dwUin, szUid)); - return dwCookie; - } - ppro->FreeCookie(dwCookie); // sending failed, free resources - SAFE_FREE(&ack->szFile); - SAFE_FREE((void**)&ack->hash); - SAFE_FREE((void**)&ack); - } - } - - return 0; // Failure -} - -DWORD avatars_server_connection::sendUploadAvatarRequest(MCONTACT hContact, WORD wRef, const BYTE *data, size_t datalen) -{ - cookie_avatar *ack = (cookie_avatar*)SAFE_MALLOC(sizeof(cookie_avatar)); - if (!ack) - return 0; // Failure: out of memory - - ack->hContact = hContact; - - DWORD dwCookie = ppro->AllocateCookie(CKT_AVATAR, ICQ_AVATAR_UPLOAD_REQUEST, 0, ack); - - icq_packet packet; - serverPacketInit(&packet, 14 + datalen); - packFNACHeader(&packet, ICQ_AVATAR_FAMILY, ICQ_AVATAR_UPLOAD_REQUEST, 0, dwCookie); - packWord(&packet, wRef); // unknown, probably reference - packWord(&packet, (WORD)datalen); - packBuffer(&packet, data, datalen); - - if (sendServerPacket(&packet)) { - ppro->debugLogA("Upload image packet sent."); - return dwCookie; - } - - ppro->ReleaseCookie(dwCookie); // failed to send, free resources - return 0; -} - -void avatars_server_connection::checkRequestQueue() -{ - mir_cslockfull alck(ppro->m_avatarsMutex); - - while (ppro->m_arAvatars.getCount() && runCount < 3) { // pick up an request and send it - happens immediatelly after login - // do not fill queue to top, leave one place free - avatars_request *pRequest = ppro->m_arAvatars[0]; - { - // rate management - mir_cslock l(m_ratesMutex); - WORD wGroup = m_rates->getGroupFromSNAC(ICQ_AVATAR_FAMILY, (WORD)(pRequest->type == ART_UPLOAD ? ICQ_AVATAR_GET_REQUEST : ICQ_AVATAR_UPLOAD_REQUEST)); - - // we are over rate, leave queue and wait - if (m_rates->getNextRateLevel(wGroup) < m_rates->getLimitLevel(wGroup, RML_ALERT)) - break; - } - - if (pRequest->type == ART_BLOCK) { // block contact processing - auto T = ppro->m_arAvatars.rev_iter(); - for (auto &ar : T) { - if (GetTickCount() > ar->timeOut) { // expired contact block, remove - delete ar; - ppro->m_arAvatars.remove(T.indexOf(&ar)); - } - } - return; // end processing - } - - ppro->m_arAvatars.remove(int(0)); - alck.unlock(); - - switch (pRequest->type) { - case ART_GET: // get avatar - sendGetAvatarRequest(pRequest->hContact, pRequest->dwUin, pRequest->szUid, pRequest->hash, pRequest->hashlen, pRequest->szFile); - break; - - case ART_UPLOAD: // set avatar - sendUploadAvatarRequest(pRequest->hContact, pRequest->wRef, pRequest->pData, pRequest->cbData); - break; - } - delete pRequest; - - alck.lock(); - } -} - -void avatars_server_connection::connectionThread() -{ - // This is the "infinite" loop that receives the packets from the ICQ avatar server - DWORD dwLastKeepAlive = time(0) + KEEPALIVE_INTERVAL; - - hPacketRecver = Netlib_CreatePacketReceiver(hConnection, 65536); - - NETLIBPACKETRECVER packetRecv = {}; - packetRecv.dwTimeout = 1000; // timeout - for stopThread to work - while (!stopThread) { - int recvResult = Netlib_GetMorePackets(hPacketRecver, &packetRecv); - if (recvResult == 0) { - ppro->debugLogA("Clean closure of avatar socket"); - break; - } - - if (recvResult == SOCKET_ERROR) { - if (GetLastError() == ERROR_TIMEOUT) { // timeout, check if we should be still running - if (Miranda_IsTerminated()) - break; - - if (time(0) >= dwLastKeepAlive) { // limit frequency (HACK: on some systems select() does not work well) - if (!ppro->m_bGatewayMode && ppro->getByte("KeepAlive", DEFAULT_KEEPALIVE_ENABLED)) { // send keep-alive packet - icq_packet packet; - packet.wLen = 0; - write_flap(&packet, ICQ_PING_CHAN); - sendServerPacket(&packet); - } - dwLastKeepAlive = time(0) + KEEPALIVE_INTERVAL; - } - - // check if we got something to request - checkRequestQueue(); - continue; - } - if (!stopThread) - ppro->debugLogA("Avatar socket closed abortively, error: %d", GetLastError()); - else - ppro->debugLogA("Avatar socket gracefully closed."); - break; - } - - // Deal with the packet - packetRecv.bytesUsed = handleServerPackets(packetRecv.buffer, packetRecv.bytesAvailable); - - if (isActive && (packetRecv.bytesAvailable == packetRecv.bytesUsed)) // no packets pending - checkRequestQueue(); // process request queue - } - { - // release connection - mir_cslock l(localSeqMutex); - NetLib_SafeCloseHandle(&hPacketRecver); // Close the packet receiver - NetLib_CloseConnection(&hConnection, FALSE); // Close the connection - } - { - // release rates - mir_cslock l(m_ratesMutex); - delete m_rates; m_rates = nullptr; - } - - SAFE_FREE((void**)&pCookie); -} - -int avatars_server_connection::sendServerPacket(icq_packet *pPacket) -{ - int lResult = 0; - - // This critsec makes sure that the sequence order doesn't get screwed up - mir_cslock l(localSeqMutex); - - if (hConnection) { - // :IMPORTANT: - // The FLAP sequence must be a WORD. When it reaches 0xFFFF it should wrap to - // 0x0000, otherwise we'll get kicked by server. - wLocalSequence++; - - // Pack sequence number - pPacket->pData[2] = ((wLocalSequence & 0xff00) >> 8); - pPacket->pData[3] = (wLocalSequence & 0x00ff); - - int nSendResult; - for (int nRetries = 3; nRetries >= 0; nRetries--) { - nSendResult = Netlib_Send(hConnection, (const char*)pPacket->pData, (int)pPacket->wLen, 0); - if (nSendResult != SOCKET_ERROR) - break; - - Sleep(1000); - } - - // Send error - if (nSendResult == SOCKET_ERROR) // thread stops automatically - ppro->debugLogA("Your connection with the ICQ avatar server was abortively closed"); - else { - lResult = 1; // packet sent successfully - - mir_cslock rlck(m_ratesMutex); - if (m_rates) - m_rates->packetSent(pPacket); - } - } - else ppro->debugLogA("Error: Failed to send packet (no connection)"); - - SAFE_FREE((void**)&pPacket->pData); - - return lResult; -} - -int avatars_server_connection::handleServerPackets(BYTE *buf, size_t buflen) -{ - BYTE channel; - WORD sequence; - size_t datalen, bytesUsed = 0; - - while (buflen > 0) { - // All FLAPS begin with 0x2a - if (*buf++ != FLAP_MARKER) - break; - - if (buflen < 6) - break; - - unpackByte(&buf, &channel); - unpackWord(&buf, &sequence); - unpackWord(&buf, &datalen); - - if (buflen < 6 + datalen) - break; - - ppro->debugLogA("Server FLAP: Channel %u, Seq %u, Length %u bytes", channel, sequence, datalen); - - switch (channel) { - case ICQ_LOGIN_CHAN: - handleLoginChannel(buf); - break; - - case ICQ_DATA_CHAN: - handleDataChannel(buf, datalen); - break; - - default: - ppro->debugLogA("Warning: Unhandled Server FLAP Channel: Channel %u, Seq %u, Length %u bytes", channel, sequence, datalen); - break; - } - - /* Increase pointers so we can check for more FLAPs */ - buf += datalen; - buflen -= (datalen + 6); - bytesUsed += (datalen + 6); - } - - return (int)bytesUsed; -} - -void avatars_server_connection::handleLoginChannel(BYTE *buf) -{ - if (*(DWORD*)buf == 0x1000000) { // here check if we received SRV_HELLO - wLocalSequence = generate_flap_sequence(); - - icq_packet packet; - serverCookieInit(&packet, (LPBYTE)pCookie, wCookieLen); - sendServerPacket(&packet); - - ppro->debugLogA("Sent CLI_IDENT to %s", "avatar server"); - - SAFE_FREE((void**)&pCookie); - wCookieLen = 0; - } - else ppro->debugLogA("Invalid Server response, Channel 1."); -} - -void avatars_server_connection::handleDataChannel(BYTE *buf, size_t datalen) -{ - snac_header snacHeader = { 0 }; - if (!unpackSnacHeader(&snacHeader, &buf, &datalen) || !snacHeader.bValid) - ppro->debugLogA("Error: Failed to parse SNAC header"); - else { - if (snacHeader.wFlags & 0x8000) - ppro->debugLogA(" Received SNAC(x%02X,x%02X), version %u", snacHeader.wFamily, snacHeader.wSubtype, snacHeader.wVersion); - else - ppro->debugLogA(" Received SNAC(x%02X,x%02X)", snacHeader.wFamily, snacHeader.wSubtype); - - switch (snacHeader.wFamily) { - case ICQ_SERVICE_FAMILY: - handleServiceFam(buf, datalen, &snacHeader); - break; - - case ICQ_AVATAR_FAMILY: - handleAvatarFam(buf, datalen, &snacHeader); - break; - - default: - ppro->debugLogA("Ignoring SNAC(x%02X,x%02X) - FAMILYx%02X not implemented", snacHeader.wFamily, snacHeader.wSubtype, snacHeader.wFamily); - break; - } - } -} - -void avatars_server_connection::handleServiceFam(BYTE *pBuffer, size_t wBufferLength, snac_header *pSnacHeader) -{ - icq_packet packet; - - switch (pSnacHeader->wSubtype) { - case ICQ_SERVER_READY: - ppro->debugLogA("Server is ready and is requesting my Family versions"); - ppro->debugLogA("Sending my Families"); - - // Miranda mimics the behaviour of Icq5 - serverPacketInit(&packet, 18); - packFNACHeader(&packet, ICQ_SERVICE_FAMILY, ICQ_CLIENT_FAMILIES); - packDWord(&packet, 0x00010004); - packDWord(&packet, 0x00100001); - sendServerPacket(&packet); - break; - - case ICQ_SERVER_FAMILIES2: - /* This is a reply to CLI_FAMILIES and it tells the client which families and their versions that this server understands. - * We send a rate request packet */ - ppro->debugLogA("Server told me his Family versions"); - ppro->debugLogA("Requesting Rate Information"); - - serverPacketInit(&packet, 10); - packFNACHeader(&packet, ICQ_SERVICE_FAMILY, ICQ_CLIENT_REQ_RATE_INFO); - sendServerPacket(&packet); - break; - - case ICQ_SERVER_RATE_INFO: - ppro->debugLogA("Server sent Rate Info"); - - /* init rates management */ - m_rates = new rates(ppro, pBuffer, wBufferLength); - - /* ack rate levels */ - ppro->debugLogA("Sending Rate Info Ack"); - - m_rates->initAckPacket(&packet); - sendServerPacket(&packet); - - // send cli_ready - serverPacketInit(&packet, 26); - packFNACHeader(&packet, ICQ_SERVICE_FAMILY, ICQ_CLIENT_READY); - packDWord(&packet, 0x00010004); // mimic ICQ 6 - packDWord(&packet, 0x0010164f); - packDWord(&packet, 0x00100001); - packDWord(&packet, 0x0010164f); - sendServerPacket(&packet); - - isActive = TRUE; // we are ready to process requests - isLoggedIn = TRUE; - - ppro->debugLogA(" *** Yeehah, login sequence complete"); - break; - - default: - ppro->debugLogA("Warning: Ignoring SNAC(x%02x,x%02x) - Unknown SNAC (Flags: %u, Ref: %u)", ICQ_SERVICE_FAMILY, pSnacHeader->wSubtype, pSnacHeader->wFlags, pSnacHeader->dwRef); - break; - } -} - -void avatars_server_connection::handleAvatarFam(BYTE *pBuffer, size_t wBufferLength, snac_header *pSnacHeader) -{ - cookie_avatar *pCookieData; - - switch (pSnacHeader->wSubtype) { - case ICQ_AVATAR_GET_REPLY: // received avatar data, store to file - // handle new avatar, notify - if (ppro->FindCookie(pSnacHeader->dwRef, nullptr, (void**)&pCookieData)) { - BYTE bResult; - { - // remove from active request list - mir_cslock l(ppro->m_avatarsMutex); - for (int i = 0; i < runCount; i++) { // look for our record - if (runContact[i] == pCookieData->hContact) { // found, remove - runContact[i] = runContact[runCount - 1]; - runTime[i] = runTime[runCount - 1]; - runCount--; - break; - } - } - } - - PROTO_AVATAR_INFORMATION ai = { 0 }; - ai.format = PA_FORMAT_JPEG; // this is for error only - ai.hContact = pCookieData->hContact; - mir_wstrncpy(ai.filename, pCookieData->szFile, _countof(ai.filename)); - AddAvatarExt(PA_FORMAT_JPEG, ai.filename); - - ppro->FreeCookie(pSnacHeader->dwRef); - - BYTE len; - - unpackByte(&pBuffer, &len); - if (wBufferLength < ((pCookieData->hashlen) << 1) + 4 + len) { - ppro->debugLogA("Received invalid avatar reply."); - - ppro->ProtoBroadcastAck(pCookieData->hContact, ACKTYPE_AVATAR, ACKRESULT_FAILED, (HANDLE)&ai, 0); - - SAFE_FREE(&pCookieData->szFile); - SAFE_FREE((void**)&pCookieData->hash); - SAFE_FREE((void**)&pCookieData); - break; - } - - pBuffer += len; - pBuffer += pCookieData->hashlen; - unpackByte(&pBuffer, &bResult); - pBuffer += pCookieData->hashlen; - - size_t datalen; - unpackWord(&pBuffer, &datalen); - - wBufferLength -= 4 + len + (pCookieData->hashlen << 1); - if (datalen > wBufferLength) { - datalen = wBufferLength; - ppro->debugLogA("Avatar reply broken, trying to do my best."); - } - - if (datalen > 4) { // store to file... - int aValid = 1; - - if (pCookieData->hashlen == 0x14 && pCookieData->hash[3] == 0x10 && ppro->getByte("StrictAvatarCheck", DEFAULT_AVATARS_CHECK)) { // check only standard hashes - mir_md5_state_t state; - BYTE digest[16]; - - mir_md5_init(&state); - mir_md5_append(&state, (const BYTE *)pBuffer, (int)datalen); - mir_md5_finish(&state, digest); - // check if received data corresponds to specified hash - if (memcmp(pCookieData->hash + 4, digest, 0x10)) aValid = 0; - } - - if (aValid) { - ppro->debugLogA("Received user avatar, storing (%d bytes).", datalen); - - const wchar_t *ptszExt; - int dwPaFormat = ProtoGetBufferFormat(pBuffer, &ptszExt); - wchar_t tszImageFile[MAX_PATH]; - mir_snwprintf(tszImageFile, L"%s%s", pCookieData->szFile, ptszExt); - - ppro->setByte(pCookieData->hContact, "AvatarType", (BYTE)dwPaFormat); - ai.format = dwPaFormat; // set the format - mir_wstrncpy(ai.filename, tszImageFile, _countof(ai.filename)); - - int out = _wopen(tszImageFile, _O_BINARY | _O_CREAT | _O_TRUNC | _O_WRONLY, _S_IREAD | _S_IWRITE); - if (out != -1) { - _write(out, pBuffer, (int)datalen); - _close(out); - - if (!pCookieData->hContact) { // our avatar, set filename - wchar_t tmp[MAX_PATH * 2]; - PathToRelativeW(tszImageFile, tmp); - ppro->setWString(NULL, "AvatarFile", tmp); - } - else { // contact's avatar set hash - DBVARIANT dbv = { DBVT_DELETED }; - if (!ppro->getSetting(pCookieData->hContact, "AvatarHash", &dbv)) { - if (ppro->setSettingBlob(pCookieData->hContact, "AvatarSaved", dbv.pbVal, dbv.cpbVal)) - ppro->debugLogA("Failed to set file hash."); - - db_free(&dbv); - } - else { - ppro->debugLogA("Warning: DB error (no hash in DB)."); - // the hash was lost, try to fix that - if (ppro->setSettingBlob(pCookieData->hContact, "AvatarSaved", pCookieData->hash, (int)pCookieData->hashlen) || - ppro->setSettingBlob(pCookieData->hContact, "AvatarHash", pCookieData->hash, (int)pCookieData->hashlen)) { - ppro->debugLogA("Failed to save avatar hash to DB"); - } - } - } - - ppro->ProtoBroadcastAck(pCookieData->hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, (HANDLE)&ai, 0); - } - } - else { // avatar is broken - ppro->debugLogA("Error: Avatar data does not match avatar hash, ignoring."); - - if (pCookieData->hContact) { - avatars_request *ar = new avatars_request(ART_BLOCK); - ar->hContact = pCookieData->hContact; - ar->timeOut = GetTickCount() + 14400000; // do not allow re-request four hours - - mir_cslock l(ppro->m_avatarsMutex); - ppro->m_arAvatars.insert(ar); - } - ppro->ProtoBroadcastAck(pCookieData->hContact, ACKTYPE_AVATAR, ACKRESULT_FAILED, (HANDLE)&ai, 0); - } - } - else { // the avatar is empty - ppro->debugLogA("Received empty avatar, nothing written (error 0x%x).", bResult); - ppro->ProtoBroadcastAck(pCookieData->hContact, ACKTYPE_AVATAR, ACKRESULT_FAILED, (HANDLE)&ai, 0); - } - SAFE_FREE(&pCookieData->szFile); - SAFE_FREE((void**)&pCookieData->hash); - SAFE_FREE((void**)&pCookieData); - } - else ppro->debugLogA("Warning: Received unexpected Avatar Reply SNAC(x10,x07)."); - break; - - case ICQ_AVATAR_UPLOAD_ACK: - // upload completed, notify - BYTE res; - unpackByte(&pBuffer, &res); - if (!res && (wBufferLength == 0x15)) { - if (ppro->FindCookie(pSnacHeader->dwRef, nullptr, (void**)&pCookieData)) // here we store the local hash - ppro->ReleaseCookie(pSnacHeader->dwRef); - else - ppro->debugLogA("Warning: Received unexpected Upload Avatar Reply SNAC(x10,x03)."); - } - else if (res) { - ppro->debugLogA("Error uploading avatar to server, #%d", res); - ppro->icq_LogMessage(LOG_WARNING, LPGEN("Error uploading avatar to server, server refused to accept the image.")); - } - else ppro->debugLogA("Received invalid upload avatar ack."); - break; - - case ICQ_ERROR: - if (ppro->FindCookie(pSnacHeader->dwRef, nullptr, (void**)&pCookieData)) { - if (pCookieData->dwUin) { - ppro->debugLogA("Error: Avatar request failed"); - SAFE_FREE(&pCookieData->szFile); - SAFE_FREE((void**)&pCookieData->hash); - } - else ppro->debugLogA("Error: Avatar upload failed"); - - ppro->ReleaseCookie(pSnacHeader->dwRef); - } - - WORD wError; - if (wBufferLength >= 2) - unpackWord(&pBuffer, &wError); - else - wError = 0; - - ppro->LogFamilyError(ICQ_AVATAR_FAMILY, wError); - break; - - default: - ppro->debugLogA("Warning: Ignoring SNAC(x%02x,x%02x) - Unknown SNAC (Flags: %u, Ref: %u)", ICQ_AVATAR_FAMILY, pSnacHeader->wSubtype, pSnacHeader->wFlags, pSnacHeader->dwRef); - break; - } -} diff --git a/protocols/IcqOscarJ/src/icq_avatar.h b/protocols/IcqOscarJ/src/icq_avatar.h deleted file mode 100644 index 6b9f935a69..0000000000 --- a/protocols/IcqOscarJ/src/icq_avatar.h +++ /dev/null @@ -1,118 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// Avatars connection support declarations -// ----------------------------------------------------------------------------- - -#ifndef __ICQ_AVATAR_H -#define __ICQ_AVATAR_H - -extern BYTE hashEmptyAvatar[9]; - -#define AVATAR_HASH_MINI 0x00 -#define AVATAR_HASH_STATIC 0x01 -#define AVATAR_HASH_FLASH 0x08 -#define AVATAR_HASH_PHOTO 0x0C - -struct CIcqProto; - -class avatars_server_connection : public MZeroedObject -{ - CIcqProto *ppro; - HNETLIBCONN hConnection; // handle to the connection - HANDLE hPacketRecver; - WORD wLocalSequence; - mir_cs localSeqMutex, connMutex; - - BOOL isLoggedIn; - BOOL isActive; - BOOL stopThread; // horrible, but simple - signal for thread to stop - - char *pCookie; // auth to server - size_t wCookieLen; - - int sendServerPacket(icq_packet *pPacket); - - int handleServerPackets(BYTE *buf, size_t buflen); - - void handleLoginChannel(BYTE *buf); - void handleDataChannel(BYTE *buf, size_t datalen); - - void handleServiceFam(BYTE *pBuffer, size_t wBufferLength, snac_header *pSnacHeader); - void handleAvatarFam(BYTE *pBuffer, size_t wBufferLength, snac_header *pSnacHeader); - - rates *m_rates; - mir_cs m_ratesMutex; - - MCONTACT runContact[4]; - DWORD runTime[4]; - int runCount; - void checkRequestQueue(); - -public: - avatars_server_connection(CIcqProto *ppro, HNETLIBCONN hConnection, char *pCookie, size_t wCookieLen); - virtual ~avatars_server_connection(); - - void connectionThread(); - void closeConnection(); - void shutdownConnection(); - - __inline mir_cs& getLock() { return connMutex; } - __inline BOOL isPending() { return !isLoggedIn; }; - __inline BOOL isReady() { return isLoggedIn && isActive && !stopThread; }; - - DWORD sendGetAvatarRequest(MCONTACT hContact, DWORD dwUin, char *szUid, const BYTE *hash, size_t hashlen, const wchar_t *file); - DWORD sendUploadAvatarRequest(MCONTACT hContact, WORD wRef, const BYTE *data, size_t datalen); -}; - -struct avatars_request : public MZeroedObject -{ - int type; - MCONTACT hContact; - DWORD dwUin; - uid_str szUid; - BYTE *hash; - size_t hashlen; - wchar_t *szFile; - BYTE *pData; - size_t cbData; - WORD wRef; - DWORD timeOut; - -public: - avatars_request(int type); - virtual ~avatars_request(); -}; - -#define ART_GET 1 -#define ART_UPLOAD 2 -#define ART_BLOCK 4 - -void AddAvatarExt(int dwFormat, wchar_t *pszDest); - -BYTE* calcMD5HashOfFile(const wchar_t *szFile); - -#endif /* __ICQ_AVATAR_H */ diff --git a/protocols/IcqOscarJ/src/icq_clients.cpp b/protocols/IcqOscarJ/src/icq_clients.cpp deleted file mode 100644 index 658a963d15..0000000000 --- a/protocols/IcqOscarJ/src/icq_clients.cpp +++ /dev/null @@ -1,1007 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// Provides capability & signature based client detection -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -const capstr capShortCaps = { 0x09, 0x46, 0x00, 0x00, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 }; // CAP_AIM_BUDDYICON - -static const char* makeClientVersion(char *szBuf, const char *szClient, unsigned v1, unsigned v2, unsigned v3, unsigned v4) -{ - if (v4) - mir_snprintf(szBuf, 64, "%s%u.%u.%u.%u", szClient, v1, v2, v3, v4); - else if (v3) - mir_snprintf(szBuf, 64, "%s%u.%u.%u", szClient, v1, v2, v3); - else - mir_snprintf(szBuf, 64, "%s%u.%u", szClient, v1, v2); - - return szBuf; -} - -static void verToStr(char *szStr, int v) -{ - char szVer[64]; - makeClientVersion(szVer, "", (v >> 24) & 0x7F, (v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF); - mir_strcat(szStr, szVer); - if (v & 0x80000000) - mir_strcat(szStr, " alpha"); -} - -static char* MirandaVersionToStringEx(char* szStr, int bUnicode, const char* szPlug, int v, int m) -{ - if (!v) // this is not Miranda - return nullptr; - - mir_strcpy(szStr, "Miranda IM "); - - if (!m && v == 1) - verToStr(szStr, 0x80010200); - else if (!m && (v & 0x7FFFFFFF) <= 0x030301) - verToStr(szStr, v); - else { - if (m) { - verToStr(szStr, m); - mir_strcat(szStr, " "); - } - if (bUnicode) - mir_strcat(szStr, "Unicode "); - - mir_strcat(szStr, "("); - mir_strcat(szStr, szPlug); - mir_strcat(szStr, " v"); - verToStr(szStr, v); - mir_strcat(szStr, ")"); - } - - return szStr; -} - -char* MirandaModToString(char* szStr, capstr* capId, int bUnicode, const char* szModName) -{ - // decode icqj mod version - DWORD mver = (*capId)[0x4] << 0x18 | (*capId)[0x5] << 0x10 | (*capId)[0x6] << 8 | (*capId)[0x7]; - DWORD iver = (*capId)[0x8] << 0x18 | (*capId)[0x9] << 0x10 | (*capId)[0xA] << 8 | (*capId)[0xB]; - DWORD scode = (*capId)[0xC] << 0x18 | (*capId)[0xD] << 0x10 | (*capId)[0xE] << 8 | (*capId)[0xF]; - - char *szClient = MirandaVersionToStringEx(szStr, bUnicode, szModName, iver, mver); - if (scode == 0x5AFEC0DE) - mir_strcat(szClient, " + SecureIM"); - - return szClient; -} - -const capstr capMirandaIm = { 'M', 'i', 'r', 'a', 'n', 'd', 'a', 'M', 0, 0, 0, 0, 0, 0, 0, 0 }; -const capstr capMirandaNg = { 'M', 'i', 'r', 'a', 'n', 'd', 'a', 'N', 0, 0, 0, 0, 0, 0, 0, 0 }; -const capstr capIcqJs7 = { 'i', 'c', 'q', 'j', ' ', 'S', 'e', 'c', 'u', 'r', 'e', ' ', 'I', 'M', 0, 0 }; -const capstr capIcqJSin = { 's', 'i', 'n', 'j', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // Miranda ICQJ S!N -const capstr capIcqJp = { 'i', 'c', 'q', 'p', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -const capstr capAimOscar = { 'M', 'i', 'r', 'a', 'n', 'd', 'a', 'A', 0, 0, 0, 0, 0, 0, 0, 0 }; -const capstr capMimMobile = { 'M', 'i', 'r', 'a', 'n', 'd', 'a', 'M', 'o', 'b', 'i', 'l', 'e', 0, 0, 0 }; -const capstr capMimPack = { 'M', 'I', 'M', '/', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // Custom Miranda Pack -const capstr capTrillian = { 0x97, 0xb1, 0x27, 0x51, 0x24, 0x3c, 0x43, 0x34, 0xad, 0x22, 0xd6, 0xab, 0xf7, 0x3f, 0x14, 0x09 }; -const capstr capTrilCrypt = { 0xf2, 0xe7, 0xc7, 0xf4, 0xfe, 0xad, 0x4d, 0xfb, 0xb2, 0x35, 0x36, 0x79, 0x8b, 0xdf, 0x00, 0x00 }; -const capstr capSim = { 'S', 'I', 'M', ' ', 'c', 'l', 'i', 'e', 'n', 't', ' ', ' ', 0, 0, 0, 0 }; -const capstr capSimOld = { 0x97, 0xb1, 0x27, 0x51, 0x24, 0x3c, 0x43, 0x34, 0xad, 0x22, 0xd6, 0xab, 0xf7, 0x3f, 0x14, 0x00 }; -const capstr capLicq = { 'L', 'i', 'c', 'q', ' ', 'c', 'l', 'i', 'e', 'n', 't', ' ', 0, 0, 0, 0 }; -const capstr capKopete = { 'K', 'o', 'p', 'e', 't', 'e', ' ', 'I', 'C', 'Q', ' ', ' ', 0, 0, 0, 0 }; -const capstr capmIcq = { 'm', 'I', 'C', 'Q', ' ', 0xA9, ' ', 'R', '.', 'K', '.', ' ', 0, 0, 0, 0 }; -const capstr capClimm = { 'c', 'l', 'i', 'm', 'm', 0xA9, ' ', 'R', '.', 'K', '.', ' ', 0, 0, 0, 0 }; -const capstr capAndRQ = { '&', 'R', 'Q', 'i', 'n', 's', 'i', 'd', 'e', 0, 0, 0, 0, 0, 0, 0 }; -const capstr capRAndQ = { 'R', '&', 'Q', 'i', 'n', 's', 'i', 'd', 'e', 0, 0, 0, 0, 0, 0, 0 }; -const capstr capIMadering = { 'I', 'M', 'a', 'd', 'e', 'r', 'i', 'n', 'g', ' ', 'C', 'l', 'i', 'e', 'n', 't' }; -const capstr capmChat = { 'm', 'C', 'h', 'a', 't', ' ', 'i', 'c', 'q', ' ', 0, 0, 0, 0, 0, 0 }; -const capstr capJimm = { 'J', 'i', 'm', 'm', ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -const capstr capCorePager = { 'C', 'O', 'R', 'E', ' ', 'P', 'a', 'g', 'e', 'r', 0, 0, 0, 0, 0, 0 }; -const capstr capDiChat = { 'D', '[', 'i', ']', 'C', 'h', 'a', 't', ' ', 0, 0, 0, 0, 0, 0, 0 }; -const capstr capVmIcq = { 'V', 'm', 'I', 'C', 'Q', ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -const capstr capSmapeR = { 'S', 'm', 'a', 'p', 'e', 'r', ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -const capstr capAnastasia = { 0x44, 0xE5, 0xBF, 0xCE, 0xB0, 0x96, 0xE5, 0x47, 0xBD, 0x65, 0xEF, 0xD6, 0xA3, 0x7E, 0x36, 0x02 }; -const capstr capPalmJicq = { 'J', 'I', 'C', 'Q', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -const capstr capInluxMsgr = { 0xA7, 0xE4, 0x0A, 0x96, 0xB3, 0xA0, 0x47, 0x9A, 0xB8, 0x45, 0xC9, 0xE4, 0x67, 0xC5, 0x6B, 0x1F }; -const capstr capYapp = { 'Y', 'a', 'p', 'p', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -const capstr capMipClient = { 0x4d, 0x49, 0x50, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x76, 0x00, 0x00, 0x00, 0x00 }; -const capstr capPigeon = { 'P', 'I', 'G', 'E', 'O', 'N', '!', 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -const capstr capDigsbyBeta = { 0x09, 0x46, 0x01, 0x05, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 0x44, 0x45, 0x45, 0x53, 0x54, 0x00 }; -const capstr capDigsby = { 'd', 'i', 'g', 's', 'b', 'y', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -const capstr capJapp = { 0x6a, 0x61, 0x70, 0x70, 0xa9, 0x20, 0x62, 0x79, 0x20, 0x53, 0x65, 0x72, 0x67, 0x6f, 0x00, 0x00 }; -const capstr capNaim = { 0xFF, 0xFF, 0xFF, 0xFF, 'n', 'a', 'i', 'm', 0, 0, 0, 0, 0, 0, 0, 0 }; -const capstr capCitron = { 0x09, 0x19, 0x19, 0x82, 0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 }; -const capstr capQip = { 0x56, 0x3F, 0xC8, 0x09, 0x0B, 0x6F, 0x41, 'Q', 'I', 'P', ' ', '2', '0', '0', '5', 'a' }; -const capstr capQipPDA = { 0x56, 0x3F, 0xC8, 0x09, 0x0B, 0x6F, 0x41, 'Q', 'I', 'P', ' ', ' ', ' ', ' ', ' ', '!' }; -const capstr capQipSymbian = { 0x51, 0xAD, 0xD1, 0x90, 0x72, 0x04, 0x47, 0x3D, 0xA1, 0xA1, 0x49, 0xF4, 0xA3, 0x97, 0xA4, 0x1F }; -const capstr capQipIphone = { 0x60, 0xDE, 0x5C, 0x8A, 0xDF, 0x8C, 0x4E, 0x1D, 0xA4, 0xC8, 0xBC, 0x3B, 0xD9, 0x79, 0x4D, 0xD8 }; -const capstr capQipMobile = { 0xB0, 0x82, 0x62, 0xF6, 0x7F, 0x7C, 0x45, 0x61, 0xAD, 0xC1, 0x1C, 0x6D, 0x75, 0x70, 0x5E, 0xC5 }; -const capstr capQipInfium = { 0x7C, 0x73, 0x75, 0x02, 0xC3, 0xBE, 0x4F, 0x3E, 0xA6, 0x9F, 0x01, 0x53, 0x13, 0x43, 0x1E, 0x1A }; -const capstr capQip2010 = { 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x0A, 0x03, 0x0B, 0x04, 0x01, 0x53, 0x00, 0x00, 0x00, 0x00 }; -const capstr capQip2012 = { 0x7F, 0x7F, 0x7C, 0x7D, 0x7E, 0x7F, 0x0A, 0x03, 0x0B, 0x04, 0x01, 0x53, 0x13, 0x43, 0x1E, 0x1A }; -const capstr capIm2 = { 0x74, 0xED, 0xC3, 0x36, 0x44, 0xDF, 0x48, 0x5B, 0x8B, 0x1C, 0x67, 0x1A, 0x1F, 0x86, 0x09, 0x9F }; // IM2 Ext Msg -const capstr capQutIm = { 'q', 'u', 't', 'i', 'm', 0x30, 0x2e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -const capstr capBayan = { 'b', 'a', 'y', 'a', 'n', 'I', 'C', 'Q', 0, 0, 0, 0, 0, 0, 0, 0 }; -const capstr capJabberJIT = { 'J', 'I', 'T', ' ', 0x76, 0x2E, 0x31, 0x2E, 0x78, 0x2E, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00 }; -const capstr capIcqKid2 = { 'I', 'c', 'q', 'K', 'i', 'd', '2', 0x00, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -const capstr capWebIcqPro = { 'W', 'e', 'b', 'I', 'c', 'q', 'P', 'r', 'o', ' ', 0, 0, 0, 0, 0, 0 }; -const capstr capJasmine = { 0x4A, 0x61, 0x73, 0x6D, 0x69, 0x6E, 0x65, 0x20, 0x76, 0x65, 0x72, 0xFF, 0x00, 0x00, 0x00, 0x00 }; -const capstr capMraJava = { 0x4a, 0x32, 0x4d, 0x45, 0x20, 0x6d, 0x40, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00 }; -const capstr capMacIcq = { 0xdd, 0x16, 0xf2, 0x02, 0x84, 0xe6, 0x11, 0xd4, 0x90, 0xdb, 0x00, 0x10, 0x4b, 0x9b, 0x4b, 0x7d }; -const capstr capIs2001 = { 0x2e, 0x7a, 0x64, 0x75, 0xfa, 0xdf, 0x4d, 0xc8, 0x88, 0x6f, 0xea, 0x35, 0x95, 0xfd, 0xb6, 0xdf }; -const capstr capIs2002 = { 0x10, 0xcf, 0x40, 0xd1, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 }; -const capstr capComm20012 = { 0xa0, 0xe9, 0x3f, 0x37, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 }; -const capstr capStrIcq = { 0xa0, 0xe9, 0x3f, 0x37, 0x4f, 0xe9, 0xd3, 0x11, 0xbc, 0xd2, 0x00, 0x04, 0xac, 0x96, 0xdd, 0x96 }; -const capstr capIcqLiteNew = { 0xc8, 0x95, 0x3a, 0x9f, 0x21, 0xf1, 0x4f, 0xaa, 0xb0, 0xb2, 0x6d, 0xe6, 0x63, 0xab, 0xf5, 0xb7 }; -const capstr capXtrazVideo = { 0x17, 0x8C, 0x2D, 0x9B, 0xDA, 0xA5, 0x45, 0xBB, 0x8D, 0xDB, 0xF3, 0xBD, 0xBD, 0x53, 0xA1, 0x0A }; -const capstr capOscarChat = { 0x74, 0x8F, 0x24, 0x20, 0x62, 0x87, 0x11, 0xD1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 }; -const capstr capUim = { 0xA7, 0xE4, 0x0A, 0x96, 0xB3, 0xA0, 0x47, 0x9A, 0xB8, 0x45, 0xC9, 0xE4, 0x67, 0xC5, 0x6B, 0x1F }; -const capstr capRambler = { 0x7E, 0x11, 0xB7, 0x78, 0xA3, 0x53, 0x49, 0x26, 0xA8, 0x02, 0x44, 0x73, 0x52, 0x08, 0xC4, 0x2A }; -const capstr capAbv = { 0x00, 0xE7, 0xE0, 0xDF, 0xA9, 0xD0, 0x4F, 0xe1, 0x91, 0x62, 0xC8, 0x90, 0x9A, 0x13, 0x2A, 0x1B }; -const capstr capNetvigator = { 0x4C, 0x6B, 0x90, 0xA3, 0x3D, 0x2D, 0x48, 0x0E, 0x89, 0xD6, 0x2E, 0x4B, 0x2C, 0x10, 0xD9, 0x9F }; -const capstr captZers = { 0xb2, 0xec, 0x8f, 0x16, 0x7c, 0x6f, 0x45, 0x1b, 0xbd, 0x79, 0xdc, 0x58, 0x49, 0x78, 0x88, 0xb9 }; // CAP_TZERS -const capstr capSimpLite = { 0x53, 0x49, 0x4D, 0x50, 0x53, 0x49, 0x4D, 0x50, 0x53, 0x49, 0x4D, 0x50, 0x53, 0x49, 0x4D, 0x50 }; -const capstr capSimpPro = { 0x53, 0x49, 0x4D, 0x50, 0x5F, 0x50, 0x52, 0x4F, 0x53, 0x49, 0x4D, 0x50, 0x5F, 0x50, 0x52, 0x4F }; -const capstr capIMsecure = { 'I', 'M', 's', 'e', 'c', 'u', 'r', 'e', 'C', 'p', 'h', 'r', 0x00, 0x00, 0x06, 0x01 }; // ZoneLabs -const capstr capIMSecKey1 = { 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // ZoneLabs -const capstr capIMSecKey2 = { 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // ZoneLabs -const capstr capFakeHtml = { 0x01, 0x38, 0xca, 0x7b, 0x76, 0x9a, 0x49, 0x15, 0x88, 0xf2, 0x13, 0xfc, 0x00, 0x97, 0x9e, 0xa8 }; -const capstr capIcqIos = { 0x09, 0x46, 0x13, 0x52, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 'D', 'E', 'S', 'T', 0x00, 0x00 }; -const capstr capIcqAndroid = { 0x09, 0x46, 0x13, 0x53, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 'D', 'E', 'S', 'T', 0x00, 0x00 }; - -const shortcapstr capAimIcon = { 0x13, 0x46 }; // CAP_AIM_BUDDYICON -const shortcapstr capAimDirect = { 0x13, 0x45 }; // CAP_AIM_DIRECTIM -const shortcapstr capAimFileShare = { 0x13, 0x48 }; // CAP_AIM_FILE_SHARE -const shortcapstr capIcqDevils = { 0x13, 0x4C }; // CAP_DEVILS -const shortcapstr capAimSmartCaps = { 0x01, 0xFF }; -const shortcapstr capAimLiveVideo = { 0x01, 0x01 }; // CAP_AIM_LIVE_VIDEO -const shortcapstr capAimLiveAudio = { 0x01, 0x04 }; // CAP_AIM_LIVE_AUDIO -const shortcapstr capStatusTextAware = { 0x01, 0x0A }; // CAP_HOST_STATUS_TEXT_AWARE - -const char* cliLibicq2k = "libicq2000"; -const char* cliLicqVer = "Licq "; -const char* cliCentericq = "Centericq"; -const char* cliLibicqUTF = "libicq2000 (Unicode)"; -const char* cliTrillian = "Trillian"; -const char* cliTrillian4 = "Trillian Astra"; -const char* cliQip = "QIP %s"; -const char* cliIM2 = "IM2"; -const char* cliSpamBot = "Spam Bot"; - -const char* CIcqProto::detectUserClient( - MCONTACT hContact, int nIsICQ, WORD wUserClass, DWORD dwOnlineSince, const char *szCurrentClient, - WORD wVersion, DWORD dwFT1, DWORD dwFT2, DWORD dwFT3, DWORD dwDirectCookie, DWORD dwWebPort, /* ICQ specific */ - BYTE *caps, size_t wLen, /* Client capabilities */ - BYTE *bClientId, /* Output: detected client-type */ - char *szClientBuf) -{ - LPCSTR szClient = nullptr; - int bMirandaIM = FALSE; - - *bClientId = CLID_ALTERNATIVE; // Most clients does not tick as MsgIDs - - // Is this a Miranda IM client? - if (dwFT1 == 0xffffffff) { - if (dwFT2 == 0xffffffff) // This is Gaim not Miranda - szClient = "Gaim"; - else if (!dwFT2 && wVersion == 7) // This is WebICQ not Miranda - szClient = "WebICQ"; - else if (!dwFT2 && dwFT3 == 0x3B7248ED) // And this is most probably Spam Bot - szClient = cliSpamBot; - else { - // Yes this is most probably Miranda, get the version info - szClient = MirandaVersionToStringEx(szClientBuf, 0, "ICQ", dwFT2, 0); - *bClientId = CLID_MIRANDA; - bMirandaIM = TRUE; - } - } - else if (dwFT1 == 0x7fffffff) { - // This is Miranda with unicode core - szClient = MirandaVersionToStringEx(szClientBuf, 1, "ICQ", dwFT2, 0); - *bClientId = CLID_MIRANDA; - bMirandaIM = TRUE; - } - else if ((dwFT1 & 0xFF7F0000) == 0x7D000000) { - // This is probably an Licq client - DWORD ver = dwFT1 & 0xFFFF; - - szClient = makeClientVersion(szClientBuf, cliLicqVer, ver / 1000, (ver / 10) % 100, ver % 10, 0); - if (dwFT1 & 0x00800000) - mir_strcat(szClientBuf, "/SSL"); - } - else if (dwFT1 == 0xffffff8f) - szClient = "StrICQ"; - else if (dwFT1 == 0xffffff42) - szClient = "mICQ"; - else if (dwFT1 == 0xffffffbe) { - unsigned ver1 = (dwFT2 >> 24) & 0xFF; - unsigned ver2 = (dwFT2 >> 16) & 0xFF; - unsigned ver3 = (dwFT2 >> 8) & 0xFF; - szClient = makeClientVersion(szClientBuf, "Alicq ", ver1, ver2, ver3, 0); - } - else if (dwFT1 == 0xFFFFFF7F) - szClient = "&RQ"; - else if (dwFT1 == 0xFFFFF666) { - // this is R&Q (Rapid Edition) - mir_snprintf(szClientBuf, 64, "R&Q %u", (unsigned)dwFT2); - szClient = szClientBuf; - } - else if (dwFT1 == 0xFFFFFFAB) - szClient = "YSM"; - else if (dwFT1 == 0x04031980) - szClient = "vICQ"; - else if ((dwFT1 == 0x3AA773EE) && (dwFT2 == 0x3AA66380)) - szClient = cliLibicq2k; - else if (dwFT1 == 0x3B75AC09) - szClient = cliTrillian; - else if (dwFT1 == 0x3BA8DBAF) { // FT2: 0x3BEB5373; FT3: 0x3BEB5262; - if (wVersion == 2) - szClient = "stICQ"; - } - else if (dwFT1 == 0xFFFFFFFE && dwFT3 == 0xFFFFFFFE) - szClient = "Jimm"; - else if (dwFT1 == 0x3FF19BEB && dwFT3 == 0x3FF19BEB) - szClient = cliIM2; - else if (dwFT1 == 0xDDDDEEFF && !dwFT2 && !dwFT3) - szClient = "SmartICQ"; - else if ((dwFT1 & 0xFFFFFFF0) == 0x494D2B00 && !dwFT2 && !dwFT3) - // last byte of FT1: (5 = Win32, 3 = SmartPhone, Pocket PC) - szClient = "IM+"; - else if (dwFT1 == 0x3B4C4C0C && !dwFT2 && dwFT3 == 0x3B7248ed) - szClient = "KXicq2"; - else if (dwFT1 == 0x66666666 && dwFT3 == 0x66666666) { - // http://darkjimm.ucoz.ru/ - if (dwFT2 == 0x10000) { - mir_strcpy(szClientBuf, "D[i]Chat v."); - mir_strcat(szClientBuf, "0.1a"); - } - else { - makeClientVersion(szClientBuf, "D[i]Chat v.", (dwFT2 >> 8) & 0x0F, (dwFT2 >> 4) & 0x0F, 0, 0); - if ((dwFT2 & 0x0F) == 1) - mir_strcat(szClientBuf, " alpha"); - else if ((dwFT2 & 0x0F) == 2) - mir_strcat(szClientBuf, " beta"); - else if ((dwFT2 & 0x0F) == 3) - mir_strcat(szClientBuf, " final"); - } - szClient = szClientBuf; - } - else if (dwFT1 == dwFT2 && dwFT2 == dwFT3 && wVersion == 8) { - if ((dwFT1 < dwOnlineSince + 3600) && (dwFT1 > (dwOnlineSince - 3600))) - szClient = cliSpamBot; - } - else if (!dwFT1 && !dwFT2 && !dwFT3 && !wVersion && !wLen && dwWebPort == 0x75BB) - szClient = cliSpamBot; - else if (dwFT1 == 0x44F523B0 && dwFT2 == 0x44F523A6 && dwFT3 == 0x44F523A6 && wVersion == 8) - szClient = "Virus"; - - // capabilities based detection - capstr *capId; - char ver[16]; - - if (nIsICQ && caps) { - // check capabilities for client identification - if (capId = MatchCapability(caps, wLen, &capMirandaIm, 8)) { - // new Miranda Signature - DWORD iver = (*capId)[0xC] << 0x18 | (*capId)[0xD] << 0x10 | (*capId)[0xE] << 8 | (*capId)[0xF]; - DWORD mver = (*capId)[0x8] << 0x18 | (*capId)[0x9] << 0x10 | (*capId)[0xA] << 8 | (*capId)[0xB]; - - szClient = MirandaVersionToStringEx(szClientBuf, dwFT1 == 0x7fffffff, "ICQ", iver, mver); - - if (MatchCapability(caps, wLen, &capIcqJs7, 0x4)) { - // detect mod - mir_strcat(szClientBuf, " (s7 & sss)"); - if (MatchCapability(caps, wLen, &capIcqJs7, 0xE)) - mir_strcat(szClientBuf, " + SecureIM"); - } - else if ((dwFT1 & 0x7FFFFFFF) == 0x7FFFFFFF) { - if (MatchCapability(caps, wLen, &capMimMobile)) - mir_strcat(szClientBuf, " (Mobile)"); - - if (dwFT3 == 0x5AFEC0DE) - mir_strcat(szClientBuf, " + SecureIM"); - } - *bClientId = CLID_MIRANDA; - bMirandaIM = TRUE; - } - else if (capId = MatchCapability(caps, wLen, &capMirandaNg, 8)) { - WORD v[4]; - BYTE *buf = *capId + 8; - unpackWord(&buf, &v[0]); unpackWord(&buf, &v[1]); unpackWord(&buf, &v[2]); unpackWord(&buf, &v[3]); - mir_snprintf(szClientBuf, MAX_PATH, "Miranda NG ICQ %d.%d.%d.%d", v[0], v[1], v[2], v[3]); - - szClient = szClientBuf; - if ((dwFT1 & 0x7FFFFFFF) == 0x7FFFFFFF && dwFT3 == 0x5AFEC0DE) - mir_strcat(szClientBuf, " + SecureIM"); - - *bClientId = CLID_MIRANDA; - bMirandaIM = TRUE; - } - else if (capId = MatchCapability(caps, wLen, &capIcqJs7, 4)) { - // detect newer icqj mod - szClient = MirandaModToString(szClientBuf, capId, dwFT3 == 0x80000000, "ICQ S7 & SSS"); - bMirandaIM = TRUE; - } - else if (capId = MatchCapability(caps, wLen, &capIcqJSin, 4)) { - // detect newer icqj mod - szClient = MirandaModToString(szClientBuf, capId, dwFT3 == 0x80000000, "ICQ S!N"); - bMirandaIM = TRUE; - } - else if (capId = MatchCapability(caps, wLen, &capIcqJp, 4)) { - // detect icqj plus mod - szClient = MirandaModToString(szClientBuf, capId, dwFT3 == 0x80000000, "ICQ Plus"); - bMirandaIM = TRUE; - } - else if (capId = MatchCapability(caps, wLen, &capJasmine, 12)) { - BYTE *p = (*capId) + 12; - szClient = makeClientVersion(szClientBuf, "Jasmine IM v", p[0], p[1], p[2], p[3]); - } - else if (capId = MatchCapability(caps, wLen, &capMraJava, 12)) { - unsigned ver1 = (*capId)[13]; - unsigned ver2 = (*capId)[14]; - - szClient = makeClientVersion(szClientBuf, "Mail.ru Agent (Java) v", ver1, ver2, 0, 0); - } - else if (MatchCapability(caps, wLen, &capTrillian) || MatchCapability(caps, wLen, &capTrilCrypt)) { - // this is Trillian, check for new versions - if (CheckContactCapabilities(hContact, CAPF_RTF)) { - if (CheckContactCapabilities(hContact, CAPF_OSCAR_FILE)) - szClient = cliTrillian4; - else { - // workaroud for a bug in Trillian - make it receive msgs, other features will not work! - ClearContactCapabilities(hContact, CAPF_SRV_RELAY); - szClient = "Trillian v3"; - } - } - else if (MatchCapability(caps, wLen, &capFakeHtml) || CheckContactCapabilities(hContact, CAPF_OSCAR_FILE)) - szClient = cliTrillian4; - else - szClient = cliTrillian; - } - else if ((capId = MatchCapability(caps, wLen, &capSimOld, 0xF)) && ((*capId)[0xF] != 0x92 && (*capId)[0xF] >= 0x20 || (*capId)[0xF] == 0)) { - int hiVer = (((*capId)[0xF]) >> 6) - 1; - unsigned loVer = (*capId)[0xF] & 0x1F; - - if ((hiVer < 0) || ((hiVer == 0) && (loVer == 0))) - szClient = "Kopete"; - else - szClient = makeClientVersion(szClientBuf, "SIM ", (unsigned)hiVer, loVer, 0, 0); - } - else if (capId = MatchCapability(caps, wLen, &capSim, 0xC)) { - unsigned ver1 = (*capId)[0xC]; - unsigned ver2 = (*capId)[0xD]; - unsigned ver3 = (*capId)[0xE]; - unsigned ver4 = (*capId)[0xF]; - - szClient = makeClientVersion(szClientBuf, "SIM ", ver1, ver2, ver3, ver4 & 0x0F); - if (ver4 & 0x80) - mir_strcat(szClientBuf, "/Win32"); - else if (ver4 & 0x40) - mir_strcat(szClientBuf, "/MacOS X"); - } - else if (capId = MatchCapability(caps, wLen, &capLicq, 0xC)) { - unsigned ver1 = (*capId)[0xC]; - unsigned ver2 = (*capId)[0xD] % 100; - unsigned ver3 = (*capId)[0xE]; - - szClient = makeClientVersion(szClientBuf, cliLicqVer, ver1, ver2, ver3, 0); - if ((*capId)[0xF]) - mir_strcat(szClientBuf, "/SSL"); - } - else if (capId = MatchCapability(caps, wLen, &capKopete, 0xC)) { - unsigned ver1 = (*capId)[0xC]; - unsigned ver2 = (*capId)[0xD]; - unsigned ver3 = (*capId)[0xE]; - unsigned ver4 = (*capId)[0xF]; - - szClient = makeClientVersion(szClientBuf, "Kopete ", ver1, ver2, ver3, ver4); - } - else if (capId = MatchCapability(caps, wLen, &capClimm, 0xC)) { - unsigned ver1 = (*capId)[0xC]; - unsigned ver2 = (*capId)[0xD]; - unsigned ver3 = (*capId)[0xE]; - unsigned ver4 = (*capId)[0xF]; - - szClient = makeClientVersion(szClientBuf, "climm ", ver1, ver2, ver3, ver4); - if ((ver1 & 0x80) == 0x80) - mir_strcat(szClientBuf, " alpha"); - if (dwFT3 == 0x02000020) - mir_strcat(szClientBuf, "/Win32"); - else if (dwFT3 == 0x03000800) - mir_strcat(szClientBuf, "/MacOS X"); - } - else if (capId = MatchCapability(caps, wLen, &capmIcq, 0xC)) { - unsigned ver1 = (*capId)[0xC]; - unsigned ver2 = (*capId)[0xD]; - unsigned ver3 = (*capId)[0xE]; - unsigned ver4 = (*capId)[0xF]; - - szClient = makeClientVersion(szClientBuf, "mICQ ", ver1, ver2, ver3, ver4); - if ((ver1 & 0x80) == 0x80) - mir_strcat(szClientBuf, " alpha"); - } - // IM2 v2 provides also Aim Icon cap - else if (MatchCapability(caps, wLen, &capIm2)) - szClient = cliIM2; - else if (capId = MatchCapability(caps, wLen, &capAndRQ, 9)) { - unsigned ver1 = (*capId)[0xC]; - unsigned ver2 = (*capId)[0xB]; - unsigned ver3 = (*capId)[0xA]; - unsigned ver4 = (*capId)[9]; - - szClient = makeClientVersion(szClientBuf, "&RQ ", ver1, ver2, ver3, ver4); - } - else if (capId = MatchCapability(caps, wLen, &capRAndQ, 9)) { - unsigned ver1 = (*capId)[0xC]; - unsigned ver2 = (*capId)[0xB]; - unsigned ver3 = (*capId)[0xA]; - unsigned ver4 = (*capId)[9]; - - szClient = makeClientVersion(szClientBuf, "R&Q ", ver1, ver2, ver3, ver4); - } - // http://imadering.com - else if (MatchCapability(caps, wLen, &capIMadering)) - szClient = "IMadering"; - else if (MatchCapability(caps, wLen, &capQipPDA)) - szClient = "QIP PDA (Windows)"; - else if (MatchCapability(caps, wLen, &capQipSymbian)) - szClient = "QIP PDA (Symbian)"; - else if (MatchCapability(caps, wLen, &capQipIphone)) - szClient = "QIP Mobile (IPhone)"; - else if (MatchCapability(caps, wLen, &capQipMobile)) - szClient = "QIP Mobile (Java)"; - else if (MatchCapability(caps, wLen, &capQipInfium)) { - mir_strcpy(szClientBuf, "QIP Infium"); - if (dwFT1) { - mir_snprintf(ver, " (%d)", dwFT1); - mir_strcat(szClientBuf, ver); - } - if (dwFT2 == 0x0B) - mir_strcat(szClientBuf, " Beta"); - - szClient = szClientBuf; - } - else if (MatchCapability(caps, wLen, &capQip2010, 12)) { - mir_strcpy(szClientBuf, "QIP 2010"); - if (dwFT1) { - mir_snprintf(ver, " (%d)", dwFT1); - mir_strcat(szClientBuf, ver); - } - - szClient = szClientBuf; - } - else if (MatchCapability(caps, wLen, &capQip2012, 12)) { - mir_strcpy(szClientBuf, "QIP 2012"); - if (dwFT1) { - mir_snprintf(ver, " (%d)", dwFT1); - mir_strcat(szClientBuf, ver); - } - - szClient = szClientBuf; - } - else if (capId = MatchCapability(caps, wLen, &capQip, 0xE)) { - if (dwFT3 == 0x0F) - mir_strcpy(ver, "2005"); - else - null_strcpy(ver, (char*)(*capId) + 11, 5); - - mir_snprintf(szClientBuf, 64, cliQip, ver); - if (dwFT1 && dwFT2 == 0x0E) { - mir_snprintf(ver, " (%d%d%d%d)", dwFT1 >> 0x18, (dwFT1 >> 0x10) & 0xFF, (dwFT1 >> 0x08) & 0xFF, dwFT1 & 0xFF); - mir_strcat(szClientBuf, ver); - } - szClient = szClientBuf; - } - else if (capId = MatchCapability(caps, wLen, &capmChat, 0xA)) { - mir_strcpy(szClientBuf, "mChat "); - mir_strncat(szClientBuf, (char*)(*capId) + 0xA, 6); - szClient = szClientBuf; - } - else if (capId = MatchCapability(caps, wLen, &capJimm, 5)) { - mir_strcpy(szClientBuf, "Jimm "); - mir_strncat(szClientBuf, (char*)(*capId) + 5, 11); - szClient = szClientBuf; - } - // http://corepager.net.ru/index/0-2 - else if (capId = MatchCapability(caps, wLen, &capCorePager, 0xA)) { - mir_strcpy(szClientBuf, "CORE Pager"); - if (dwFT2 == 0x0FFFF0011 && dwFT3 == 0x1100FFFF && (dwFT1 >> 0x18)) { - mir_snprintf(ver, " %d.%d", dwFT1 >> 0x18, (dwFT1 >> 0x10) & 0xFF); - if ((dwFT1 & 0xFF) == 0x0B) - mir_strcat(ver, " Beta"); - mir_strcat(szClientBuf, ver); - } - szClient = szClientBuf; - } - // http://darkjimm.ucoz.ru/ - else if (capId = MatchCapability(caps, wLen, &capDiChat, 9)) { - mir_strcpy(szClientBuf, "D[i]Chat"); - mir_strncat(szClientBuf, (char*)(*capId) + 8, 8); - szClient = szClientBuf; - } - else if (MatchCapability(caps, wLen, &capMacIcq)) - szClient = "ICQ for Mac"; - else if (MatchCapability(caps, wLen, &capUim)) - szClient = "uIM"; - // http://chis.nnov.ru/anastasia - else if (MatchCapability(caps, wLen, &capAnastasia)) - szClient = "Anastasia"; - // http://www.jsoft.ru - else if (capId = MatchCapability(caps, wLen, &capPalmJicq, 0xC)) { - unsigned ver1 = (*capId)[0xC]; - unsigned ver2 = (*capId)[0xD]; - unsigned ver3 = (*capId)[0xE]; - unsigned ver4 = (*capId)[0xF]; - szClient = makeClientVersion(szClientBuf, "JICQ ", ver1, ver2, ver3, ver4); - } - // http://www.inlusoft.com - else if (MatchCapability(caps, wLen, &capInluxMsgr)) - szClient = "Inlux Messenger"; - // http://mip.rufon.net - else if (capId = MatchCapability(caps, wLen, &capMipClient, 0xC)) { - unsigned ver1 = (*capId)[0xC]; - unsigned ver2 = (*capId)[0xD]; - unsigned ver3 = (*capId)[0xE]; - unsigned ver4 = (*capId)[0xF]; - if (ver1 < 30) - makeClientVersion(szClientBuf, "MIP ", ver1, ver2, ver3, ver4); - else { - mir_strcpy(szClientBuf, "MIP "); - mir_strncat(szClientBuf, (char*)(*capId) + 11, 5); - } - szClient = szClientBuf; - } - //http://mip.rufon.net - new signature - else if (capId = MatchCapability(caps, wLen, &capMipClient, 0x04)) { - mir_strcpy(szClientBuf, "MIP "); - mir_strncat(szClientBuf, (char*)(*capId) + 4, 12); - szClient = szClientBuf; - } - else if (capId = MatchCapability(caps, wLen, &capVmIcq, 0x06)) { - mir_strcpy(szClientBuf, "VmICQ"); - mir_strncat(szClientBuf, (char*)(*capId) + 5, 11); - szClient = szClientBuf; - } - // http://www.smape.com/smaper - else if (capId = MatchCapability(caps, wLen, &capSmapeR, 0x07)) { - mir_strcpy(szClientBuf, "SmapeR"); - mir_strncat(szClientBuf, (char*)(*capId) + 6, 10); - szClient = szClientBuf; - } - // http://yapp.ru - else if (capId = MatchCapability(caps, wLen, &capYapp, 0x04)) { - mir_strcpy(szClientBuf, "Yapp! v"); - mir_strncat(szClientBuf, (char*)(*capId) + 8, 5); - szClient = szClientBuf; - } - // http://www.dibsby.com (newer builds) - else if (MatchCapability(caps, wLen, &capDigsby, 0x06)) - szClient = "Digsby"; - // http://www.digsby.com - probably by mistake (feature detection as well) - else if (MatchCapability(caps, wLen, &capDigsbyBeta)) - szClient = "Digsby"; - // http://www.japp.org.ua - else if (MatchCapability(caps, wLen, &capJapp)) - szClient = "japp"; - // http://pigeon.vpro.ru - else if (MatchCapability(caps, wLen, &capPigeon, 0x07)) - szClient = "PIGEON!"; - // http://www.qutim.org - else if (capId = MatchCapability(caps, wLen, &capQutIm, 0x05)) { - if ((*capId)[0x6] == 0x2E) { // old qutim id - unsigned ver1 = (*capId)[0x5] - 0x30; - unsigned ver2 = (*capId)[0x7] - 0x30; - makeClientVersion(szClientBuf, "qutIM ", ver1, ver2, 0, 0); - } - else { // new qutim id - unsigned ver1 = (*capId)[0x6]; - unsigned ver2 = (*capId)[0x7]; - unsigned ver3 = (*capId)[0x8]; - unsigned ver4 = ((*capId)[0x9] << 8) || (*capId)[0xA]; - - makeClientVersion(szClientBuf, "qutIM ", ver1, ver2, ver3, ver4); - - switch ((*capId)[0x5]) { - case 'l': - mir_strcat(szClientBuf, "/Linux"); - break; - case 'w': - mir_strcat(szClientBuf, "/Win32"); - break; - case 'm': - mir_strcat(szClientBuf, "/MacOS X"); - break; - } - } - szClient = szClientBuf; - } - // http://www.barobin.com/bayanICQ.html - else if (capId = MatchCapability(caps, wLen, &capBayan, 8)) { - mir_strcpy(szClientBuf, "bayanICQ "); - mir_strncat(szClientBuf, (char*)(*capId) + 8, 5); - szClient = szClientBuf; - } - else if (capId = MatchCapability(caps, wLen, &capJabberJIT, 0x04)) - szClient = "Jabber ICQ Transport"; - // http://sourceforge.net/projects/icqkid2 - else if (capId = MatchCapability(caps, wLen, &capIcqKid2, 0x07)) { - unsigned ver1 = (*capId)[0x7]; - unsigned ver2 = (*capId)[0x8]; - unsigned ver3 = (*capId)[0x9]; - unsigned ver4 = (*capId)[0xA]; - szClient = makeClientVersion(szClientBuf, "IcqKid2 v", ver1, ver2, ver3, ver4); - } - // http://intrigue.ru/workshop/webicqpro/webicqpro.html - else if (capId = MatchCapability(caps, wLen, &capWebIcqPro, 0x0A)) - szClient = "WebIcqPro"; - // http://www.citron-im.com - else if (capId = MatchCapability(caps, wLen, &capCitron)) - szClient = "Citron IM"; - // try to determine which client is behind libicq2000 - else if (szClient == cliLibicq2k) { - if (CheckContactCapabilities(hContact, CAPF_RTF)) - szClient = cliCentericq; // centericq added rtf capability to libicq2000 - else if (CheckContactCapabilities(hContact, CAPF_UTF)) - szClient = cliLibicqUTF; // IcyJuice added unicode capability to libicq2000 - // others - like jabber transport uses unmodified library, thus cannot be detected - } - // THE SIGNATURE DETECTION ENDS HERE, after this only feature default will be detected - else if (szClient == nullptr) { - // ZA mangled the version, OMG! - if (wVersion == 8 && CheckContactCapabilities(hContact, CAPF_XTRAZ) && (MatchCapability(caps, wLen, &capIMSecKey1, 6) || MatchCapability(caps, wLen, &capIMSecKey2, 6))) - wVersion = ICQ_VERSION; - - // try to determine 2001-2003 versions - if (wVersion == 8 && (MatchCapability(caps, wLen, &capComm20012) || CheckContactCapabilities(hContact, CAPF_SRV_RELAY))) { - if (MatchCapability(caps, wLen, &capIs2001)) { - if (!dwFT1 && !dwFT2 && !dwFT3) { - if (CheckContactCapabilities(hContact, CAPF_RTF)) - szClient = "TICQClient"; // possibly also older GnomeICU - else - szClient = "ICQ for Pocket PC"; - } - else { - *bClientId = CLID_GENERIC; - szClient = "ICQ 2001"; - } - } - else if (MatchCapability(caps, wLen, &capIs2002)) { - *bClientId = CLID_GENERIC; - szClient = "ICQ 2002"; - } - else if (CheckContactCapabilities(hContact, CAPF_SRV_RELAY | CAPF_UTF | CAPF_RTF)) { - if (!dwFT1 && !dwFT2 && !dwFT3) { - if (!dwWebPort) - szClient = "GnomeICU 0.99.5+"; // no other way - else - szClient = "IC@"; - } - else { - *bClientId = CLID_GENERIC; - szClient = "ICQ 2002/2003a"; - } - } - // libpurple (e.g. Pidgin 2.7.x) - else if (CheckContactCapabilities(hContact, CAPF_SRV_RELAY | CAPF_UTF | CAPF_TYPING | CAPF_XTRAZ) && - MatchCapability(caps, wLen, &capOscarChat) && MatchShortCapability(caps, wLen, &capAimIcon) && - MatchCapability(caps, wLen, &capFakeHtml)) { - if (MatchShortCapability(caps, wLen, &capAimDirect)) - szClient = "libpurple"; - else - szClient = "Meebo"; - } - else if (CheckContactCapabilities(hContact, CAPF_SRV_RELAY | CAPF_UTF | CAPF_TYPING)) { - if (!dwFT1 && !dwFT2 && !dwFT3) - szClient = "PreludeICQ"; - } - } - else if (wVersion == 8) { - if (CheckContactCapabilities(hContact, CAPF_UTF | CAPF_TYPING) && MatchShortCapability(caps, wLen, &capAimIcon) && MatchShortCapability(caps, wLen, &capAimDirect)) - szClient = "imo.im"; //https://imo.im/ - Web IM - } - // try to determine lite versions - else if (wVersion >= 9) { - if (CheckContactCapabilities(hContact, CAPF_XTRAZ)) { - *bClientId = CLID_GENERIC; - if (CheckContactCapabilities(hContact, CAPF_OSCAR_FILE)) { - if (MatchCapability(caps, wLen, &captZers)) { - // capable of tZers ? - if (MatchCapability(caps, wLen, &capIcqLiteNew) && MatchShortCapability(caps, wLen, &capStatusTextAware) && - MatchShortCapability(caps, wLen, &capAimLiveVideo) && MatchShortCapability(caps, wLen, &capAimLiveAudio)) { - mir_strcpy(szClientBuf, "ICQ 7"); - } - else if (MatchCapability(caps, wLen, &capFakeHtml)) { - if (MatchShortCapability(caps, wLen, &capAimLiveVideo) && MatchShortCapability(caps, wLen, &capAimLiveAudio)) { - mir_strcpy(szClientBuf, "ICQ 6"); - *bClientId = CLID_ICQ6; - } - else if (CheckContactCapabilities(hContact, CAPF_RTF) && !CheckContactCapabilities(hContact, CAPF_CONTACTS) && MatchShortCapability(caps, wLen, &capIcqDevils)) { - mir_strcpy(szClientBuf, "Qnext v4"); // finally handles SRV_RELAY correctly - *bClientId = CLID_ALTERNATIVE; - } - } - else mir_strcpy(szClientBuf, "icq5.1"); - } - else mir_strcpy(szClientBuf, "icq5"); - - if (MatchCapability(caps, wLen, &capRambler)) - mir_strcat(szClientBuf, " (Rambler)"); - else if (MatchCapability(caps, wLen, &capAbv)) - mir_strcat(szClientBuf, " (Abv)"); - else if (MatchCapability(caps, wLen, &capNetvigator)) - mir_strcat(szClientBuf, " (Netvigator)"); - - szClient = szClientBuf; - } - else if (!CheckContactCapabilities(hContact, CAPF_ICQDIRECT)) { - *bClientId = CLID_ALTERNATIVE; - if (CheckContactCapabilities(hContact, CAPF_RTF)) { - // most probably Qnext - try to make that shit at least receiving our msgs - ClearContactCapabilities(hContact, CAPF_SRV_RELAY); - debugLogA("Forcing simple messages (QNext client)."); - szClient = "Qnext"; - } - else if (CheckContactCapabilities(hContact, CAPF_TYPING) && MatchCapability(caps, wLen, &captZers) && MatchCapability(caps, wLen, &capFakeHtml)) { - if (CheckContactCapabilities(hContact, CAPF_SRV_RELAY | CAPF_UTF) && MatchShortCapability(caps, wLen, &capAimLiveAudio)) - szClient = "Mail.ru Agent (PC)"; - else - szClient = "Fring"; - } - else szClient = "pyICQ"; - } - else szClient = "ICQ Lite v4"; - } - else if (MatchCapability(caps, wLen, &capIcqLiteNew)) - szClient = "ICQ Lite"; // the new ICQ Lite based on ICQ6 - else if (!CheckContactCapabilities(hContact, CAPF_ICQDIRECT)) { - if (MatchCapability(caps, wLen, &capFakeHtml) && MatchCapability(caps, wLen, &capOscarChat) && MatchShortCapability(caps, wLen, &capAimSmartCaps)) - szClient = cliTrillian4; - else if (CheckContactCapabilities(hContact, CAPF_UTF) && !CheckContactCapabilities(hContact, CAPF_RTF)) - szClient = "pyICQ"; - } - } - else if (wVersion == 7) { - if (CheckContactCapabilities(hContact, CAPF_RTF)) - szClient = "GnomeICU"; // this is an exception - else if (CheckContactCapabilities(hContact, CAPF_SRV_RELAY)) { - if (!dwFT1 && !dwFT2 && !dwFT3) - szClient = "&RQ"; - else { - *bClientId = CLID_GENERIC; - szClient = "ICQ 2000"; - } - } - else if (CheckContactCapabilities(hContact, CAPF_UTF)) { - if (CheckContactCapabilities(hContact, CAPF_TYPING)) - szClient = "Icq2Go! (Java)"; - else if (wUserClass & CLASS_WIRELESS) - szClient = "Pocket Web 1&1"; - else - szClient = "Icq2Go!"; - } - } - else if (wVersion == 0xA) { - if (!CheckContactCapabilities(hContact, CAPF_RTF) && !CheckContactCapabilities(hContact, CAPF_UTF)) { - // this is bad, but we must do it - try to detect QNext - ClearContactCapabilities(hContact, CAPF_SRV_RELAY); - debugLogA("Forcing simple messages (QNext client)."); - szClient = "Qnext"; - } - else if (!CheckContactCapabilities(hContact, CAPF_RTF) && CheckContactCapabilities(hContact, CAPF_UTF) && !dwFT1 && !dwFT2 && !dwFT3) - // not really good, but no other option - szClient = "NanoICQ"; - } - else if (wVersion == 0xB) { - if (CheckContactCapabilities(hContact, CAPF_XTRAZ | CAPF_SRV_RELAY | CAPF_TYPING | CAPF_UTF) && MatchShortCapability(caps, wLen, &capIcqDevils)) - szClient = "Mail.ru Agent (Symbian)"; - } - else if (wVersion == 0) { - // capability footprint based detection - not really reliable - if (!dwFT1 && !dwFT2 && !dwFT3 && !dwWebPort && !dwDirectCookie) { - // DC info is empty - if (CheckContactCapabilities(hContact, CAPF_UTF | CAPF_CONTACTS | CAPF_XTRAZ | CAPF_OSCAR_FILE)) - szClient = "ICQ 8"; - else if (CheckContactCapabilities(hContact, CAPF_TYPING) && MatchCapability(caps, wLen, &capIs2001) && - MatchCapability(caps, wLen, &capIs2002) && MatchCapability(caps, wLen, &capComm20012)) - szClient = cliSpamBot; - else if (MatchShortCapability(caps, wLen, &capAimIcon) && MatchShortCapability(caps, wLen, &capAimDirect) && - CheckContactCapabilities(hContact, CAPF_OSCAR_FILE | CAPF_UTF)) { // detect libgaim/libpurple versions - if (CheckContactCapabilities(hContact, CAPF_SRV_RELAY)) - szClient = "Adium X"; // yeah, AFAIK only Adium has this fixed - else if (CheckContactCapabilities(hContact, CAPF_TYPING)) - szClient = "libpurple"; - else - szClient = "libgaim"; - } - else if (MatchShortCapability(caps, wLen, &capAimIcon) && MatchShortCapability(caps, wLen, &capAimDirect) && - MatchCapability(caps, wLen, &capOscarChat) && CheckContactCapabilities(hContact, CAPF_OSCAR_FILE) && wLen == 0x40) - szClient = "libgaim"; // Gaim 1.5.1 most probably - else if (CheckContactCapabilities(hContact, CAPF_OSCAR_FILE) && MatchCapability(caps, wLen, &capOscarChat) && wLen == 0x20) - szClient = "Easy Message"; - else if (CheckContactCapabilities(hContact, CAPF_UTF | CAPF_TYPING) && MatchShortCapability(caps, wLen, &capAimIcon) && MatchCapability(caps, wLen, &capOscarChat) && wLen == 0x40) - szClient = "Meebo"; - else if (CheckContactCapabilities(hContact, CAPF_UTF) && MatchShortCapability(caps, wLen, &capAimIcon) && wLen == 0x20) - szClient = "PyICQ-t Jabber Transport"; - else if (CheckContactCapabilities(hContact, CAPF_UTF | CAPF_XTRAZ) && MatchShortCapability(caps, wLen, &capAimIcon) && MatchCapability(caps, wLen, &capXtrazVideo)) - szClient = "PyICQ-t Jabber Transport"; - else if (CheckContactCapabilities(hContact, CAPF_UTF | CAPF_SRV_RELAY | CAPF_ICQDIRECT | CAPF_TYPING) && wLen == 0x40) - szClient = "Agile Messenger"; // Smartphone 2002 - else if (CheckContactCapabilities(hContact, CAPF_UTF | CAPF_SRV_RELAY | CAPF_ICQDIRECT | CAPF_OSCAR_FILE) && MatchShortCapability(caps, wLen, &capAimFileShare)) - szClient = "Slick"; // http://lonelycatgames.com/?app=slick - else if (CheckContactCapabilities(hContact, CAPF_UTF | CAPF_SRV_RELAY | CAPF_OSCAR_FILE | CAPF_CONTACTS) && MatchShortCapability(caps, wLen, &capAimFileShare) && MatchShortCapability(caps, wLen, &capAimIcon)) - szClient = "Digsby"; // http://www.digsby.com - else if (CheckContactCapabilities(hContact, CAPF_UTF | CAPF_SRV_RELAY | CAPF_CONTACTS) && MatchShortCapability(caps, wLen, &capAimIcon) && MatchCapability(caps, wLen, &capFakeHtml)) - szClient = "mundu IM"; // http://messenger.mundu.com - else if (CheckContactCapabilities(hContact, CAPF_UTF | CAPF_OSCAR_FILE) && MatchCapability(caps, wLen, &capOscarChat)) { - if (CheckContactCapabilities(hContact, CAPF_TYPING)) - szClient = "eBuddy"; // http://www.ebuddy.com - else - szClient = "eBuddy (Mobile)"; - } - else if (CheckContactCapabilities(hContact, CAPF_CONTACTS | CAPF_OSCAR_FILE) && MatchShortCapability(caps, wLen, &capAimIcon) && MatchShortCapability(caps, wLen, &capAimDirect) && MatchCapability(caps, wLen, &capOscarChat)) - szClient = "IloveIM"; //http://www.iloveim.com/ - - } - } - } - } - else if (!nIsICQ) { - // detect AIM clients - if (caps) { - if (capId = MatchCapability(caps, wLen, &capAimOscar, 8)) { - // AimOscar Signature - DWORD aver = (*capId)[0xC] << 0x18 | (*capId)[0xD] << 0x10 | (*capId)[0xE] << 8 | (*capId)[0xF]; - DWORD mver = (*capId)[0x8] << 0x18 | (*capId)[0x9] << 0x10 | (*capId)[0xA] << 8 | (*capId)[0xB]; - szClient = MirandaVersionToStringEx(szClientBuf, 0, "AimOscar", aver, mver); - bMirandaIM = TRUE; - } - else if (capId = MatchCapability(caps, wLen, &capSim, 0xC)) { - // Sim is universal - unsigned ver1 = (*capId)[0xC]; - unsigned ver2 = (*capId)[0xD]; - unsigned ver3 = (*capId)[0xE]; - szClient = makeClientVersion(szClientBuf, "SIM ", ver1, ver2, ver3, 0); - - if ((*capId)[0xF] & 0x80) - mir_strcat(szClientBuf, "/Win32"); - else if ((*capId)[0xF] & 0x40) - mir_strcat(szClientBuf, "/MacOS X"); - } - else if (capId = MatchCapability(caps, wLen, &capKopete, 0xC)) { - unsigned ver1 = (*capId)[0xC]; - unsigned ver2 = (*capId)[0xD]; - unsigned ver3 = (*capId)[0xE]; - unsigned ver4 = (*capId)[0xF]; - szClient = makeClientVersion(szClientBuf, "Kopete ", ver1, ver2, ver3, ver4); - } - else if (MatchCapability(caps, wLen, &capIcqIos) || MatchCapability(caps, wLen, &capIcqAndroid)) - szClient = "ICQ (Mobile)"; - else if (MatchCapability(caps, wLen, &capIm2)) - // IM2 extensions - szClient = cliIM2; - else if (MatchCapability(caps, wLen, &capNaim, 0x8)) - szClient = "naim"; - // http://www.dibsby.com - else if (MatchCapability(caps, wLen, &capDigsby, 0x06) || MatchCapability(caps, wLen, &capDigsbyBeta)) - szClient = "Digsby"; - else if (MatchShortCapability(caps, wLen, &capAimIcon) && MatchCapability(caps, wLen, &capOscarChat) && - CheckContactCapabilities(hContact, CAPF_UTF | CAPF_TYPING) && wLen == 0x40) - szClient = "Meebo"; - // libpurple (e.g. Pidgin 2.7.x) - else if (wLen == 0x90 && CheckContactCapabilities(hContact, CAPF_SRV_RELAY | CAPF_UTF | CAPF_TYPING | CAPF_XTRAZ) && - MatchCapability(caps, wLen, &capOscarChat) && MatchShortCapability(caps, wLen, &capAimIcon) && - MatchShortCapability(caps, wLen, &capAimDirect) && MatchCapability(caps, wLen, &capFakeHtml)) - szClient = "libpurple"; - // libpurple - Meebo (without DirectIM and OFT) - else if (wLen == 0x70 && CheckContactCapabilities(hContact, CAPF_SRV_RELAY | CAPF_UTF | CAPF_TYPING | CAPF_XTRAZ) && - MatchCapability(caps, wLen, &capOscarChat) && MatchShortCapability(caps, wLen, &capAimIcon) && - MatchCapability(caps, wLen, &capFakeHtml)) - szClient = "Meebo"; - else - szClient = "AIM"; - } - else if (wUserClass & CLASS_WIRELESS) - szClient = "AIM (Mobile)"; - else { - DWORD dwUin; - uid_str szUid; - getContactUid(hContact, &dwUin, &szUid); - if (szUid[0]) { - if (strstr(szUid, "@bk.ru") || strstr(szUid, "@list.ru") || strstr(szUid, "@mail.ru") || strstr(szUid, "@inbox.ru")) - szClient = "MRA client"; - } - - if (szClient == nullptr) - szClient = "AIM"; - } - } - - // custom miranda packs - if (caps && bMirandaIM) { - capId = MatchCapability(caps, wLen, &capMimPack, 4); - if (capId) { - char szPack[16]; - mir_snprintf(szPack, " [%.12s]", (*capId) + 4); - - // make sure client string is not constant - if (szClient != szClientBuf) { - mir_strcpy(szClientBuf, szClient); - szClient = szClientBuf; - } - - mir_strcat(szClientBuf, szPack); - } - } - - BOOL bClientDetected = (szClient != nullptr); - - // client detection failed, provide default clients - if (!szClient) { - *bClientId = CLID_GENERIC; - switch (wVersion) { - case 6: - szClient = "ICQ99"; - break; - case 7: - szClient = "ICQ 2000/Icq2Go"; - break; - case 8: - szClient = "ICQ 2001-2003a"; - break; - case 9: - szClient = "ICQ Lite"; - break; - case 0xA: - szClient = "ICQ 2003b"; - } - } - - if (szClient) { - char *szExtra = nullptr; - - if (MatchCapability(caps, wLen, &capSimpLite)) - szExtra = " + SimpLite"; - else if (MatchCapability(caps, wLen, &capSimpPro)) - szExtra = " + SimpPro"; - else if (MatchCapability(caps, wLen, &capIMsecure) || MatchCapability(caps, wLen, &capIMSecKey1, 6) || MatchCapability(caps, wLen, &capIMSecKey2, 6)) - szExtra = " + IMsecure"; - - if (szExtra) { - if (szClient != szClientBuf) { - mir_strcpy(szClientBuf, szClient); - szClient = szClientBuf; - } - mir_strcat(szClientBuf, szExtra); - } - } - - // Log the detection result if it has changed or contact just logged on... - if (!szCurrentClient || mir_strcmp(szCurrentClient, szClient)) { - if (bClientDetected) - debugLogA("Client identified as %s", szClient); - else - debugLogA("No client identification, put default ICQ client for protocol."); - } - - return szClient; -} diff --git a/protocols/IcqOscarJ/src/icq_constants.h b/protocols/IcqOscarJ/src/icq_constants.h deleted file mode 100644 index eb8a1e2533..0000000000 --- a/protocols/IcqOscarJ/src/icq_constants.h +++ /dev/null @@ -1,645 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// Global constants and default settings are defined here -// ----------------------------------------------------------------------------- -// Most of the protocol constants follow the naming conventions of the -// Oscar documentation at http://iserverd.khstu.ru/oscar/index.html -// BIG THANKS to Alexandr for maintaining this site and to everyone -// in the ICQ devel community who have helped to collect the data. - -#ifndef __ICQ_CONSTANTS_H -#define __ICQ_CONSTANTS_H - -/* Static icon indexes */ -#define ISI_AUTH_REQUEST 0 -#define ISI_AUTH_GRANT 1 -#define ISI_AUTH_REVOKE 2 -#define ISI_ADD_TO_SERVLIST 3 - -/* Contact menu item indexes */ -#define ICMI_ADD_TO_SERVLIST 0 -#define ICMI_XSTATUS_DETAILS 1 -#define ICMI_OPEN_PROFILE 2 - -/* Some default settings */ -#define DEFAULT_SERVER_PORT 5190 -#define DEFAULT_SERVER_PORT_SSL 443 -#define DEFAULT_SERVER_HOST "login.icq.com" -#define DEFAULT_SERVER_HOST_SSL "slogin.icq.com" -#define DEFAULT_SS_ENABLED 1 -#define DEFAULT_SS_ADDSERVER 1 -#define DEFAULT_SS_LOAD 0 -#define DEFAULT_SS_STORE 1 -#define DEFAULT_SS_GROUP "General" - -#define DEFAULT_SECURE_LOGIN 1 -#define DEFAULT_SECURE_CONNECTION 1 -#define DEFAULT_LEGACY_FIX 0 -#define DEFAULT_KEEPALIVE_ENABLED 1 -#define DEFAULT_ANSI_CODEPAGE CP_ACP -#define DEFAULT_DCMSG_ENABLED 1 // passive dc messaging is default -#define DEFAULT_TEMPVIS_ENABLED 1 // temporary visible is enabled by default -#define DEFAULT_MTN_ENABLED 1 -#define DEFAULT_AVATARS_ENABLED 1 -#define DEFAULT_LOAD_AVATARS 1 -#define DEFAULT_BIGGER_AVATARS 0 -#define DEFAULT_AVATARS_CHECK 1 -#define DEFAULT_XSTATUS_ENABLED 1 -#define DEFAULT_XSTATUS_AUTO 1 -#define DEFAULT_XSTATUS_RESET 0 -#define DEFAULT_MOODS_ENABLED 1 -#define DEFAULT_KILLSPAM_ENABLED 1 - -#define DEFAULT_SLOWSEND 1 - -#define DEFAULT_POPUPS_ENABLED 1 -#define DEFAULT_SPAM_POPUPS_ENABLED 1 -#define DEFAULT_LOG_POPUPS_ENABLED 1 -#define DEFAULT_POPUPS_SYS_ICONS 1 -#define DEFAULT_LOG0_TEXT_COLORS RGB(0,0,0) // LOG_NOTE -#define DEFAULT_LOG0_BACK_COLORS RGB(255,255,255) -#define DEFAULT_LOG0_TIMEOUT 0 -#define DEFAULT_LOG1_TEXT_COLORS RGB(0,0,0) // LOG_WARNING -#define DEFAULT_LOG1_BACK_COLORS RGB(255,255,255) -#define DEFAULT_LOG1_TIMEOUT 0 -#define DEFAULT_LOG2_TEXT_COLORS RGB(0,0,0) // LOG_ERROR -#define DEFAULT_LOG2_BACK_COLORS RGB(255,255,255) -#define DEFAULT_LOG2_TIMEOUT 0 -#define DEFAULT_LOG3_TEXT_COLORS RGB(0,0,0) // LOG_FATAL -#define DEFAULT_LOG3_BACK_COLORS RGB(255,255,255) -#define DEFAULT_LOG3_TIMEOUT 0 -#define DEFAULT_SPAM_TEXT_COLORS RGB(193,0,38) -#define DEFAULT_SPAM_BACK_COLORS RGB(213,209,208) -#define DEFAULT_SPAM_TIMEOUT 0 -#define DEFAULT_POPUPS_WIN_COLORS 0 -#define DEFAULT_POPUPS_DEF_COLORS (BYTE)!DEFAULT_POPUPS_WIN_COLORS - -/* Database setting names */ -#define DBSETTING_CAPABILITIES "caps" -// Contact's server-list items -#define DBSETTING_SERVLIST_ID "ServerId" -#define DBSETTING_SERVLIST_GROUP "SrvGroupId" -#define DBSETTING_SERVLIST_PERMIT "SrvPermitId" -#define DBSETTING_SERVLIST_DENY "SrvDenyId" -#define DBSETTING_SERVLIST_IGNORE "SrvIgnoreId" -// Owner's server-list items -#define DBSETTING_SERVLIST_PRIVACY "SrvVisibilityID" -#define DBSETTING_SERVLIST_PHOTO "SrvPhotoID" -#define DBSETTING_SERVLIST_AVATAR "SrvAvatarID" -#define DBSETTING_SERVLIST_METAINFO "SrvMetaInfoID" -#define DBSETTING_SERVLIST_UNHANDLED "SrvUnhandledIDList" -// Contact's data from server-list -#define DBSETTING_SERVLIST_DATA "ServerData" -// User Details -#define DBSETTING_METAINFO_TOKEN "MetaInfoToken" -#define DBSETTING_METAINFO_TIME "MetaInfoTime" -#define DBSETTING_METAINFO_SAVED "InfoTS" -// Status Note & Mood -#define DBSETTING_STATUS_NOTE "StatusNote" -#define DBSETTING_STATUS_NOTE_TIME "StatusNoteTS" -#define DBSETTING_STATUS_MOOD "StatusMood" -// Custom Status -#define DBSETTING_XSTATUS_ID "XStatusId" -#define DBSETTING_XSTATUS_NAME "XStatusName" -#define DBSETTING_XSTATUS_MSG "XStatusMsg" - - -// Status FLAGS (used to determine status of other users) -#define ICQ_STATUSF_ONLINE 0x0000 -#define ICQ_STATUSF_AWAY 0x0001 -#define ICQ_STATUSF_DND 0x0002 -#define ICQ_STATUSF_NA 0x0004 -#define ICQ_STATUSF_OCCUPIED 0x0010 -#define ICQ_STATUSF_FFC 0x0020 -#define ICQ_STATUSF_INVISIBLE 0x0100 - -// Status values (used to set own status) -#define ICQ_STATUS_ONLINE 0x0000 -#define ICQ_STATUS_AWAY 0x0001 -#define ICQ_STATUS_NA 0x0005 -#define ICQ_STATUS_OCCUPIED 0x0011 -#define ICQ_STATUS_DND 0x0013 -#define ICQ_STATUS_FFC 0x0020 -#define ICQ_STATUS_INVISIBLE 0x0100 - -#define STATUS_WEBAWARE 0x0001 // Status webaware flag -#define STATUS_SHOWIP 0x0002 // Status show ip flag -#define STATUS_BIRTHDAY 0x0008 // User birthday flag -#define STATUS_WEBFRONT 0x0020 // User active webfront flag -#define STATUS_DCDISABLED 0x0100 // Direct connection not supported -#define STATUS_DCAUTH 0x1000 // Direct connection upon authorization -#define STATUS_DCCONT 0x2000 // DC only with contact users - - - -// Typing notification statuses -#define MTN_FINISHED 0x0000 -#define MTN_TYPED 0x0001 -#define MTN_BEGUN 0x0002 -#define MTN_WINDOW_CLOSED 0x000F - - - -// Ascii Capability IDs -#define CAP_RTFMSGS "{97B12751-243C-4334-AD22-D6ABF73F1492}" -#define CAP_UTF8MSGS "{0946134E-4C7F-11D1-8222-444553540000}" - -// Binary Capability Sizes -#define BINARY_CAP_SIZE 16 -#define BINARY_SHORT_CAP_SIZE 2 - -// Binary Capability IDs -#define CAP_SRV_RELAY 0x09, 0x46, 0x13, 0x49, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 -#define CAP_UTF 0x09, 0x46, 0x13, 0x4e, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 -#define CAP_RTF 0x97, 0xb1, 0x27, 0x51, 0x24, 0x3c, 0x43, 0x34, 0xad, 0x22, 0xd6, 0xab, 0xf7, 0x3f, 0x14, 0x92 -#define CAP_CONTACTS 0x09, 0x46, 0x13, 0x4b, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 -#define CAP_TYPING 0x56, 0x3f, 0xc8, 0x09, 0x0b, 0x6f, 0x41, 0xbd, 0x9f, 0x79, 0x42, 0x26, 0x09, 0xdf, 0xa2, 0xf3 -#define CAP_ICQDIRECT 0x09, 0x46, 0x13, 0x44, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 -#define CAP_XTRAZ 0x1A, 0x09, 0x3C, 0x6C, 0xD7, 0xFD, 0x4E, 0xC5, 0x9D, 0x51, 0xA6, 0x47, 0x4E, 0x34, 0xF5, 0xA0 -#define CAP_OSCAR_FILE 0x09, 0x46, 0x13, 0x43, 0x4C, 0x7F, 0x11, 0xD1, 0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00 - -// Miranda IM Capability bitmask -#define CAPF_SRV_RELAY 0x00000001 -#define CAPF_UTF 0x00000002 -#define CAPF_RTF 0x00000004 -#define CAPF_CONTACTS 0x00000010 -#define CAPF_TYPING 0x00000020 -#define CAPF_ICQDIRECT 0x00000080 -#define CAPF_XTRAZ 0x00000100 -#define CAPF_OSCAR_FILE 0x00000400 -#define CAPF_STATUS_MESSAGES 0x10000000 -#define CAPF_STATUS_MOOD 0x40000000 -#define CAPF_XSTATUS 0x80000000 - - -// Message Capability IDs -#define MCAP_SRV_RELAY_FMT_s 0x09461349, 0x4c7f11d1, 0x82224445, 0x53540000 -#define MCAP_REVERSE_DC_REQ_s 0x09461344, 0x4c7f11d1, 0x82224445, 0x53540000 -#define MCAP_FILE_TRANSFER_s 0x09461343, 0x4c7f11d1, 0x82224445, 0x53540000 -#define MCAP_CONTACTS_s 0x0946134b, 0x4c7f11d1, 0x82224445, 0x53540000 - -// Plugin Type GUIDs -#define PSIG_MESSAGE_s 0x00000000, 0x00000000, 0x00000000, 0x00000000 -#define PSIG_INFO_PLUGIN_s 0xa0e93f37, 0x4fe9d311, 0xbcd20004, 0xac96dd96 -#define PSIG_STATUS_PLUGIN_s 0x10cf40d1, 0x4fe9d311, 0xbcd20004, 0xac96dd96 - -// Plugin Message GUIDs -#define PMSG_QUERY_INFO_s 0xF002BF71, 0x4371D311, 0x8DD20010, 0x4B06462E -#define PMSG_QUERY_STATUS_s 0x10180670, 0x5471D311, 0x8DD20010, 0x4B06462E - - - -// Message types -#define MTYPE_PLAIN 0x01 // Plain text (simple) message -#define MTYPE_CHAT 0x02 // Chat request message -#define MTYPE_FILEREQ 0x03 // File request / file ok message -#define MTYPE_URL 0x04 // URL message (0xFE formatted) -#define MTYPE_AUTHREQ 0x06 // Authorization request message (0xFE formatted) -#define MTYPE_AUTHDENY 0x07 // Authorization denied message (0xFE formatted) -#define MTYPE_AUTHOK 0x08 // Authorization given message (empty) -#define MTYPE_SERVER 0x09 // Message from OSCAR server (0xFE formatted) -#define MTYPE_ADDED 0x0C // "You-were-added" message (0xFE formatted) -#define MTYPE_WWP 0x0D // Web pager message (0xFE formatted) -#define MTYPE_EEXPRESS 0x0E // Email express message (0xFE formatted) -#define MTYPE_CONTACTS 0x13 // Contact list message -#define MTYPE_PLUGIN 0x1A // Plugin message described by text string -#define MTYPE_AUTOONLINE 0xE7 // Auto online message (internal only) -#define MTYPE_AUTOAWAY 0xE8 // Auto away message -#define MTYPE_AUTOBUSY 0xE9 // Auto occupied message -#define MTYPE_AUTONA 0xEA // Auto not available message -#define MTYPE_AUTODND 0xEB // Auto do not disturb message -#define MTYPE_AUTOFFC 0xEC // Auto free for chat message -// Internal Message types -#define MTYPE_UNKNOWN 0x00 // Unknown message - -#define MTYPE_GREETINGCARD 0x101 // Greeting Card -#define MTYPE_REQUESTCONTACTS 0x102 // Request for Contacts -#define MTYPE_MESSAGE 0x103 // Message+ -#define MTYPE_STATUSMSGEXT 0x104 // StatusMsgExt (2003b) -#define MTYPE_SMS_MESSAGE 0x110 // SMS message from Mobile -#define MTYPE_SCRIPT_INVITATION 0x201 // Xtraz Invitation -#define MTYPE_SCRIPT_DATA 0x202 // Xtraz Message -#define MTYPE_SCRIPT_NOTIFY 0x208 // Xtraz Response -#define MTYPE_REVERSE_REQUEST 0x401 // Reverse DC request - -// Message Plugin Type GUIDs -#define MGTYPE_MESSAGE_s 0xBE6B7305, 0x0FC2104F, 0xA6DE4DB1, 0xE3564B0E -#define MGTYPE_STATUSMSGEXT_s 0x811a18bc, 0x0e6c1847, 0xa5916f18, 0xdcc76f1a -#define MGTYPE_FILE_s 0xF02D12D9, 0x3091D311, 0x8DD70010, 0x4B06462E -#define MGTYPE_WEBURL_s 0x371C5872, 0xE987D411, 0xA4C100D0, 0xB759B1D9 -#define MGTYPE_CONTACTS_s 0x2A0E7D46, 0x7676D411, 0xBCE60004, 0xAC961EA6 -#define MGTYPE_GREETING_CARD_s 0x01E53B48, 0x2AE4D111, 0xB6790060, 0x97E1E294 -#define MGTYPE_CHAT_s 0xBFF720B2, 0x378ED411, 0xBD280004, 0xAC96D905 -#define MGTYPE_SMS_MESSAGE_s 0x0e28f600, 0x11e7d311, 0xbcf30004, 0xac969dc2 -#define MGTYPE_XTRAZ_SCRIPT_s 0x3b60b3ef, 0xd82a6c45, 0xa4e09c5a, 0x5e67e865 - -// Message Plugin Sub-Type IDs -#define MGTYPE_STANDARD_SEND 0x0000 -#define MGTYPE_CONTACTS_REQUEST 0x0002 -#define MGTYPE_SCRIPT_INVITATION 0x0001 -#define MGTYPE_SCRIPT_DATA 0x0002 -#define MGTYPE_SCRIPT_USER_REMOVE 0x0004 -#define MGTYPE_SCRIPT_NOTIFY 0x0008 -#define MGTYPE_UNDEFINED 0xFFFF - - - -/* Channels */ -#define ICQ_LOGIN_CHAN 0x01 -#define ICQ_DATA_CHAN 0x02 -#define ICQ_ERROR_CHAN 0x03 -#define ICQ_CLOSE_CHAN 0x04 -#define ICQ_PING_CHAN 0x05 - -/* Families */ -#define ICQ_SERVICE_FAMILY 0x0001 -#define ICQ_LOCATION_FAMILY 0x0002 -#define ICQ_BUDDY_FAMILY 0x0003 -#define ICQ_MSG_FAMILY 0x0004 -#define ICQ_BOS_FAMILY 0x0009 -#define ICQ_LOOKUP_FAMILY 0x000a -#define ICQ_STATS_FAMILY 0x000b -#define ICQ_CHAT_NAVIGATION_FAMILY 0x000d -#define ICQ_CHAT_FAMILY 0x000e -#define ICQ_AVATAR_FAMILY 0x0010 -#define ICQ_LISTS_FAMILY 0x0013 -#define ICQ_EXTENSIONS_FAMILY 0x0015 -#define ICQ_AUTHORIZATION_FAMILY 0x0017 -#define ICQ_DIRECTORY_FAMILY 0x0025 - -/* Subtypes for Service Family 0x0001 */ -#define ICQ_ERROR 0x0001 -#define ICQ_CLIENT_READY 0x0002 -#define ICQ_SERVER_READY 0x0003 -#define ICQ_CLIENT_NEW_SERVICE 0x0004 -#define ICQ_SERVER_REDIRECT_SERVICE 0x0005 -#define ICQ_CLIENT_REQ_RATE_INFO 0x0006 -#define ICQ_SERVER_RATE_INFO 0x0007 -#define ICQ_CLIENT_RATE_ACK 0x0008 -#define ICQ_SERVER_RATE_CHANGE 0x000a -#define ICQ_SERVER_PAUSE 0x000b -#define ICQ_CLIENT_PAUSE_ACK 0x000c -#define ICQ_SERVER_RESUME 0x000d -#define ICQ_CLIENT_REQINFO 0x000e -#define ICQ_SERVER_NAME_INFO 0x000f -#define ICQ_SERVER_EVIL_NOTICE 0x0010 -#define ICQ_CLIENT_SET_IDLE 0x0011 -#define ICQ_SERVER_MIGRATIONREQ 0x0012 -#define ICQ_SERVER_MOTD 0x0013 -#define ICQ_CLIENT_FAMILIES 0x0017 -#define ICQ_SERVER_FAMILIES2 0x0018 -#define ICQ_CLIENT_SET_STATUS 0x001e -#define ICQ_SERVER_EXTSTATUS 0x0021 - -/* Subtypes for Location Family 0x0002 */ -#define ICQ_LOCATION_CLI_REQ_RIGHTS 0x0002 -#define ICQ_LOCATION_RIGHTS_REPLY 0x0003 -#define ICQ_LOCATION_SET_USER_INFO 0x0004 -#define ICQ_LOCATION_REQ_USER_INFO 0x0005 -#define ICQ_LOCATION_USR_INFO_REPLY 0x0006 -#define ICQ_LOCATION_QRY_USER_INFO 0x0015 - -/* Subtypes for Buddy Family 0x0003 */ -#define ICQ_USER_CLI_REQBUDDY 0x0002 -#define ICQ_USER_SRV_REPLYBUDDY 0x0003 -#define ICQ_USER_ADDTOLIST 0x0004 /* deprecated */ -#define ICQ_USER_REMOVEFROMLIST 0x0005 /* deprecated */ -#define ICQ_USER_NOTIFY_REJECTED 0x000a -#define ICQ_USER_ONLINE 0x000b -#define ICQ_USER_OFFLINE 0x000c -#define ICQ_USER_ADDTOTEMPLIST 0x000f -#define ICQ_USER_REMOVEFROMTEMPLIST 0x0010 - -/* Subtypes for Message Family 0x0004 */ -#define ICQ_MSG_SRV_ERROR 0x0001 -#define ICQ_MSG_CLI_SETPARAMS 0x0002 -#define ICQ_MSG_CLI_RESETPARAMS 0x0003 -#define ICQ_MSG_CLI_REQICBM 0x0004 -#define ICQ_MSG_SRV_REPLYICBM 0x0005 -#define ICQ_MSG_SRV_SEND 0x0006 -#define ICQ_MSG_SRV_RECV 0x0007 -#define ICQ_MSG_SRV_MISSED_MESSAGE 0x000A -#define ICQ_MSG_RESPONSE 0x000B -#define ICQ_MSG_SRV_ACK 0x000C -#define ICQ_MSG_CLI_REQ_OFFLINE 0x0010 -#define ICQ_MSG_MTN 0x0014 -#define ICQ_MSG_SRV_OFFLINE_REPLY 0x0017 - -/* Subtypes for Privacy Family 0x0009 */ -#define ICQ_PRIVACY_REQ_RIGHTS 0x0002 -#define ICQ_PRIVACY_RIGHTS_REPLY 0x0003 -#define ICQ_CLI_ADDVISIBLE 0x0005 -#define ICQ_CLI_REMOVEVISIBLE 0x0006 -#define ICQ_CLI_ADDINVISIBLE 0x0007 -#define ICQ_CLI_REMOVEINVISIBLE 0x0008 -#define ICQ_PRIVACY_SERVICE_ERROR 0x0009 -#define ICQ_CLI_ADDTEMPVISIBLE 0x000A -#define ICQ_CLI_REMOVETEMPVISIBLE 0x000B - -/* Subtypes for Lookup Family 0x000a */ -#define ICQ_LOOKUP_REQUEST 0x0002 -#define ICQ_LOOKUP_EMAIL_REPLY 0x0003 - -/* Subtypes for Stats Family 0x000b */ -#define ICQ_STATS_MINREPORTINTERVAL 0x0002 - -/* Subtypes for Avatar Family 0x0010 */ -#define ICQ_AVATAR_ERROR 0x0001 -#define ICQ_AVATAR_UPLOAD_REQUEST 0x0002 -#define ICQ_AVATAR_UPLOAD_ACK 0x0003 -#define ICQ_AVATAR_GET_REQUEST 0x0006 -#define ICQ_AVATAR_GET_REPLY 0x0007 - -/* Subtypes for Server Lists Family 0x0013 */ -#define ICQ_LISTS_ERROR 0x0001 -#define ICQ_LISTS_CLI_REQLISTS 0x0002 -#define ICQ_LISTS_SRV_REPLYLISTS 0x0003 -#define ICQ_LISTS_CLI_REQUEST 0x0004 -#define ICQ_LISTS_CLI_CHECK 0x0005 -#define ICQ_LISTS_LIST 0x0006 -#define ICQ_LISTS_GOTLIST 0x0007 -#define ICQ_LISTS_ADDTOLIST 0x0008 -#define ICQ_LISTS_UPDATEGROUP 0x0009 -#define ICQ_LISTS_REMOVEFROMLIST 0x000A -#define ICQ_LISTS_ACK 0x000E -#define ICQ_LISTS_UPTODATE 0x000F -#define ICQ_LISTS_CLI_MODIFYSTART 0x0011 -#define ICQ_LISTS_CLI_MODIFYEND 0x0012 -#define ICQ_LISTS_GRANTAUTH 0x0014 -#define ICQ_LISTS_AUTHGRANTED 0x0015 -#define ICQ_LISTS_REVOKEAUTH 0x0016 -#define ICQ_LISTS_REQUESTAUTH 0x0018 -#define ICQ_LISTS_AUTHREQUEST 0x0019 -#define ICQ_LISTS_CLI_AUTHRESPONSE 0x001A -#define ICQ_LISTS_SRV_AUTHRESPONSE 0x001B -#define ICQ_LISTS_YOUWEREADDED 0x001C - -/* Subtypes for ICQ Extensions Family 0x0015 */ -#define ICQ_META_ERROR 0x0001 -#define ICQ_META_CLI_REQUEST 0x0002 -#define ICQ_META_SRV_REPLY 0x0003 -#define ICQ_META_SRV_UPDATE 0x0004 - -/* Subtypes for Authorization Family 0x0017 */ -#define ICQ_SIGNON_ERROR 0x0001 -#define ICQ_SIGNON_LOGIN_REQUEST 0x0002 -#define ICQ_SIGNON_LOGIN_REPLY 0x0003 -#define ICQ_SIGNON_REGISTRATION_REQ 0x0004 -#define ICQ_SIGNON_NEW_UIN 0x0005 -#define ICQ_SIGNON_AUTH_REQUEST 0x0006 -#define ICQ_SIGNON_AUTH_KEY 0x0007 -#define ICQ_SIGNON_REQUEST_IMAGE 0x000C -#define ICQ_SIGNON_REG_AUTH_IMAGE 0x000D - -// Class constants -#define CLASS_UNCONFIRMED 0x0001 -#define CLASS_ADMINISTRATOR 0x0002 -#define CLASS_AOL 0x0004 -#define CLASS_COMMERCIAL 0x0008 -#define CLASS_FREE 0x0010 -#define CLASS_AWAY 0x0020 -#define CLASS_ICQ 0x0040 -#define CLASS_WIRELESS 0x0080 -#define CLASS_FORWARDING 0x0200 -#define CLASS_BOT 0x0400 - -// Reply types for SNAC 15/02 & 15/03 -#define CLI_DELETE_OFFLINE_MSGS_REQ 0x003E -#define CLI_META_INFO_REQ 0x07D0 -#define SRV_META_INFO_REPLY 0x07DA - -// Reply subtypes for SNAC 15/02 & 15/03 -#define META_PROCESSING_ERROR 0x0001 // Meta processing error server reply -#define META_SMS_DELIVERY_RECEIPT 0x0096 // Server SMS response (delivery receipt) -#define META_SET_PASSWORD_ACK 0x00AA // Set user password server ack -#define META_UNREGISTER_ACK 0x00B4 // Unregister account server ack -#define META_BASIC_USERINFO 0x00C8 // User basic info reply -#define META_WORK_USERINFO 0x00D2 // User work info reply -#define META_MORE_USERINFO 0x00DC // User more info reply -#define META_NOTES_USERINFO 0x00E6 // User notes (about) info reply -#define META_EMAIL_USERINFO 0x00EB // User extended email info reply -#define META_INTERESTS_USERINFO 0x00F0 // User interests info reply -#define META_AFFILATIONS_USERINFO 0x00FA // User past/affilations info reply -#define META_SHORT_USERINFO 0x0104 // Short user information reply -#define META_HPAGECAT_USERINFO 0x010E // User homepage category information reply -#define SRV_USER_FOUND 0x01A4 // Search: user found reply -#define SRV_LAST_USER_FOUND 0x01AE // Search: last user found reply -#define META_REGISTRATION_STATS_ACK 0x0302 // Registration stats ack -#define SRV_RANDOM_FOUND 0x0366 // Random search server reply -#define META_SET_PASSWORD_REQ 0x042E // Set user password request -#define META_REQUEST_FULL_INFO 0x04B2 // Request full user info -#define META_REQUEST_SHORT_INFO 0x04BA // Request short user info -#define META_REQUEST_SELF_INFO 0x04D0 // Request full self user info -#define META_SEARCH_GENERIC 0x055F // Search user by details (TLV) -#define META_SEARCH_UIN 0x0569 // Search user by UIN (TLV) -#define META_SEARCH_EMAIL 0x0573 // Search user by E-mail (TLV) -#define META_DIRECTORY_QUERY 0x0FA0 -#define META_DIRECTORY_DATA 0x0FAA -#define META_DIRECTORY_RESPONSE 0x0FB4 -#define META_DIRECTORY_UPDATE 0x0FD2 -#define META_DIRECTORY_UPDATE_ACK 0x0FDC - -#define META_XML_INFO 0x08A2 // Server variable requested via xml -#define META_SET_FULLINFO_REQ 0x0C3A // Set full user info request -#define META_SET_FULLINFO_ACK 0x0C3F // Server ack for set fullinfo command -#define META_SPAM_REPORT_ACK 0x2012 // Server ack for user spam report - -// Subtypes for Directory meta requests (family 0x5b9) -#define DIRECTORY_QUERY_INFO 0x0002 -#define DIRECTORY_SET_INFO 0x0003 -#define DIRECTORY_QUERY_MULTI_INFO 0x0006 -#define DIRECTORY_QUERY_INFO_ACK 0x0009 -#define DIRECTORY_SET_INFO_ACK 0x000A - -// TLV types - -// SECURITY flags -#define TLV_AUTH 0x02F8 // uint8 User authorization permissions -#define TLV_WEBAWARE 0x030C // uint8 User 'show web status' permissions - - -// SEARCH only TLVs -#define TLV_AGERANGE 0x0168 // acombo Age range to search -#define TLV_KEYWORDS 0x0226 // sstring Whitepages search keywords string -#define TLV_ONLINEONLY 0x0230 // uint8 Search only online users flag -#define TLV_UIN 0x0136 // uint32 User uin - -// common -#define TLV_FIRSTNAME 0x0140 // sstring User firstname -#define TLV_LASTNAME 0x014A // sstring User lastname -#define TLV_NICKNAME 0x0154 // sstring User nickname -#define TLV_EMAIL 0x015E // ecombo User email -#define TLV_GENDER 0x017C // uint8 User gender -#define TLV_MARITAL 0x033E // uint8 User marital status -#define TLV_LANGUAGE 0x0186 // uint16 User spoken language -#define TLV_CITY 0x0190 // sstring User home city name -#define TLV_STATE 0x019A // sstring User home state abbr -#define TLV_COUNTRY 0x01A4 // uint16 User home country code -#define TLV_COMPANY 0x01AE // sstring User work company name -#define TLV_DEPARTMENT 0x01B8 // sstring User work department name -#define TLV_POSITION 0x01C2 // sstring User work position (title) -#define TLV_OCUPATION 0x01CC // uint16 User work ocupation code -#define TLV_PASTINFO 0x01D6 // icombo User affilations node -#define TLV_AFFILATIONS 0x01FE // icombo User past info node -#define TLV_INTERESTS 0x01EA // icombo User interests node -#define TLV_HOMEPAGE 0x0212 // sstring User homepage category/keywords - -// changeinfo -#define TLV_AGE 0x0172 // uint16 User age -#define TLV_URL 0x0213 // sstring User homepage url -#define TLV_BIRTH 0x023A // bcombo User birthday info (year, month, day) -#define TLV_ABOUT 0x0258 // sstring User notes (about) text -#define TLV_STREET 0x0262 // sstring User home street address -#define TLV_ZIPCODE 0x026D // sstring User home zip code -#define TLV_PHONE 0x0276 // sstring User home phone number -#define TLV_FAX 0x0280 // sstring User home fax number -#define TLV_MOBILE 0x028A // sstring User home cellular phone number -#define TLV_WORKSTREET 0x0294 // sstring User work street address -#define TLV_WORKCITY 0x029E // sstring User work city name -#define TLV_WORKSTATE 0x02A8 // sstring User work state name -#define TLV_WORKCOUNTRY 0x02B2 // uint16 User work country code -#define TLV_WORKZIPCODE 0x02BD // sstring User work zip code -#define TLV_WORKPHONE 0x02C6 // sstring User work phone number -#define TLV_WORKFAX 0x02D0 // sstring User work fax number -#define TLV_WORKURL 0x02DA // sstring User work webpage url -#define TLV_TIMEZONE 0x0316 // uint8 User GMT offset -#define TLV_ORGCITY 0x0320 // sstring User originally from city -#define TLV_ORGSTATE 0x032A // sstring User originally from state -#define TLV_ORGCOUNTRY 0x0334 // uint16 User originally from country (code) -#define TLV_ALLOWSPAM 0x0348 // uint8 -#define TLV_CODEPAGE 0x0352 // uint16 Codepage used for details - - -/* Direct packet types */ -#define PEER_INIT 0xFF -#define PEER_INIT_ACK 0x01 -#define PEER_MSG_INIT 0x03 -#define PEER_MSG 0x02 -#define PEER_FILE_INIT 0x00 -#define PEER_FILE_INIT_ACK 0x01 -#define PEER_FILE_NEXTFILE 0x02 -#define PEER_FILE_RESUME 0x03 -#define PEER_FILE_STOP 0x04 -#define PEER_FILE_SPEED 0x05 -#define PEER_FILE_DATA 0x06 - -/* Direct command types */ -#define DIRECT_CANCEL 0x07D0 /* 2000 TCP cancel previous file/chat request */ -#define DIRECT_ACK 0x07DA /* 2010 TCP acknowledge message packet */ -#define DIRECT_MESSAGE 0x07EE /* 2030 TCP message */ - -// DC types -#define DC_DISABLED 0x0000 // Direct connection disabled / auth required -#define DC_HTTPS 0x0001 // Direct connection thru firewall or https proxy -#define DC_SOCKS 0x0002 // Direct connection thru socks4/5 proxy server -#define DC_NORMAL 0x0004 // Normal direct connection (without proxy/firewall) -#define DC_WEB 0x0006 // Web client - no direct connection - -// Message flags -#define MFLAG_NORMAL 0x01 // Normal message -#define MFLAG_AUTO 0x03 // Auto-message flag -#define MFLAG_MULTI 0x80 // This is multiple recipients message - -// Some SSI constants -#define SSI_ITEM_BUDDY 0x0000 // Buddy record (name: uin for ICQ and screenname for AIM) -#define SSI_ITEM_GROUP 0x0001 // Group record -#define SSI_ITEM_PERMIT 0x0002 // Permit record ("Allow" list in AIM, and "Visible" list in ICQ) -#define SSI_ITEM_DENY 0x0003 // Deny record ("Block" list in AIM, and "Invisible" list in ICQ) -#define SSI_ITEM_VISIBILITY 0x0004 // Permit/deny settings or/and bitmask of the AIM classes -#define SSI_ITEM_PRESENCE 0x0005 // Presence info (if others can see your idle status, etc) -#define SSI_ITEM_CLIENTDATA 0x0009 // Client specific, e.g. ICQ2k shortcut bar items -#define SSI_ITEM_IGNORE 0x000e // Ignore list record. -#define SSI_ITEM_LASTUPDATE 0x000f // Item that contain roster update time (name: "LastUpdateDate") -#define SSI_ITEM_NONICQ 0x0010 // Non-ICQ contact (to send SMS). Name: 1#EXT, 2#EXT, etc -#define SSI_ITEM_UNKNOWN2 0x0011 // Unknown. -#define SSI_ITEM_IMPORTTIME 0x0013 // Item that contain roster import time (name: "Import time") -#define SSI_ITEM_BUDDYICON 0x0014 // Buddy icon info. (names: "1", "8", etc. according ot the icon type) -#define SSI_ITEM_SAVED 0x0019 -#define SSI_ITEM_PREAUTH 0x001B -#define SSI_ITEM_METAINFO 0x0020 // Owner Details' token & last update time - -#define SSI_TLV_AWAITING_AUTH 0x0066 // Contact not authorized in list -#define SSI_TLV_NOT_IN_LIST 0x006A // Always empty -#define SSI_TLV_UNKNOWN 0x006D // WTF ? -#define SSI_TLV_SUBITEMS 0x00C8 // List of sub-items IDs -#define SSI_TLV_VISIBILITY 0x00CA -#define SSI_TLV_SHORTCUT 0x00CD -#define SSI_TLV_TIMESTAMP 0x00D4 // Import Timestamp -#define SSI_TLV_AVATARHASH 0x00D5 -#define SSI_TLV_NAME 0x0131 // Custom contact nickname -#define SSI_TLV_GROUP_OPENNED 0x0134 -#define SSI_TLV_EMAIL 0x0137 // Custom contact email -#define SSI_TLV_PHONE 0x0138 // Custom contact phone number -#define SSI_TLV_PHONE_CELLULAR 0x0139 // Custom contact cellphone number -#define SSI_TLV_PHONE_SMS 0x013A // Custom contact SMS number -#define SSI_TLV_COMMENT 0x013C // User comment -#define SSI_TLV_METAINFO_TOKEN 0x015C // Privacy token for Contact's details -#define SSI_TLV_METAINFO_TIME 0x015D // Contact's details last update time - -#define MAX_SSI_TLV_NAME_SIZE 0x40 -#define MAX_SSI_TLV_COMMENT_SIZE 0x50 - -// Client ID constants (internal) -#define CLID_GENERIC 0x00 // Generic clients (eg. older official clients) -#define CLID_ALTERNATIVE 0x01 // Clients not using tick for MsgID (most third-party clients) -#define CLID_MIRANDA 0x02 // Hey, that's mate! -#define CLID_ICQ6 0x10 // Mark ICQ6 as it has some non obvious limitations! - - -// Internal Constants -#define ICQ_PROTOCOL_NAME "ICQ" -#define ICQ_PLUG_VERSION PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM) -#define ICQ_VERSION 11 // Protocol version -#define DC_TYPE DC_NORMAL // Used for DC settings -#define MAX_CONTACTSSEND 15 -#define MAX_MESSAGESNACSIZE 8000 -#define CLIENTRATELIMIT 0 -#define COOKIE_TIMEOUT 3600 // One hour -#define KEEPALIVE_INTERVAL 57 // Slightly less than a minute -#define WEBFRONTPORT 0x50 -#define CLIENTFEATURES 0x3 -#define URL_FORGOT_PASSWORD "https://www.icq.com/password/" -#define URL_REGISTER "https://www.icq.com/register/" -#define FLAP_MARKER 0x2a -#define CLIENT_MD5_STRING "AOL Instant Messenger (SM)" -#define UNIQUEIDSETTING "UIN" -#define UINMAXLEN 11 // DWORD string max len + 1 -#define PASSWORDMAXLEN 16 -#define OSCAR_PROXY_HOST "ars.icq.com" -#define OSCAR_PROXY_VERSION 0x044A - -#define CLIENT_ID_STRING "ICQ Client" // Client identification, mimic ICQ 6.5 -#define CLIENT_ID_CODE 0x010a -#define CLIENT_VERSION_MAJOR 0x0014 -#define CLIENT_VERSION_MINOR 0x0034 -#define CLIENT_VERSION_LESSER 0x0000 -#define CLIENT_VERSION_BUILD 0x0c18 -#define CLIENT_DISTRIBUTION 0x00000611 -#define CLIENT_LANGUAGE "en" -#define CLIENT_COUNTRY "us" - -#endif /* __ICQ_CONSTANTS_H */ diff --git a/protocols/IcqOscarJ/src/icq_db.cpp b/protocols/IcqOscarJ/src/icq_db.cpp deleted file mode 100644 index 4026cb3acf..0000000000 --- a/protocols/IcqOscarJ/src/icq_db.cpp +++ /dev/null @@ -1,207 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// Internal Database API -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -int CIcqProto::getSetting(MCONTACT hContact, const char *szSetting, DBVARIANT *dbv) -{ - return db_get_s(hContact, m_szModuleName, szSetting, dbv, 0); -} - -double CIcqProto::getSettingDouble(MCONTACT hContact, const char *szSetting, double dDef) -{ - DBVARIANT dbv = { DBVT_DELETED }; - double dRes; - - if (getSetting(hContact, szSetting, &dbv)) - return dDef; // not found, give default - - if (dbv.type != DBVT_BLOB || dbv.cpbVal != sizeof(double)) - dRes = dDef; - else - dRes = *(double*)dbv.pbVal; - - db_free(&dbv); - return dRes; -} - -DWORD CIcqProto::getContactUin(MCONTACT hContact) -{ - return getDword(hContact, UNIQUEIDSETTING, 0); -} - -int CIcqProto::getContactUid(MCONTACT hContact, DWORD *pdwUin, uid_str *ppszUid) -{ - DBVARIANT dbv = { DBVT_DELETED }; - int iRes = 1; - - *pdwUin = 0; - if (ppszUid) *ppszUid[0] = '\0'; - - if (!getSetting(hContact, UNIQUEIDSETTING, &dbv)) { - switch (dbv.type) { - case DBVT_DWORD: - *pdwUin = dbv.dVal; - iRes = 0; - break; - - case DBVT_ASCIIZ: - if (ppszUid) { - mir_strcpy(*ppszUid, dbv.pszVal); - iRes = 0; - } - else debugLogA("AOL screennames not accepted"); - break; - - case DBVT_UTF8: - if (ppszUid) { - mir_strcpy(*ppszUid, dbv.pszVal); - mir_utf8decode(*ppszUid, nullptr); - iRes = 0; - } - else debugLogA("AOL screennames not accepted"); - break; - } - db_free(&dbv); - } - return iRes; -} - -char* CIcqProto::getSettingStringUtf(MCONTACT hContact, const char *szModule, const char *szSetting, char *szDef) -{ - DBVARIANT dbv = { DBVT_DELETED }; - if (db_get_utf(hContact, szModule, szSetting, &dbv)) { - db_free(&dbv); // for a setting with invalid contents/type - return null_strdup(szDef); - } - - char *szRes = null_strdup(dbv.pszVal); - db_free(&dbv); - return szRes; -} - -char* CIcqProto::getSettingStringUtf(MCONTACT hContact, const char *szSetting, char *szDef) -{ - return getSettingStringUtf(hContact, m_szModuleName, szSetting, szDef); -} - -WORD CIcqProto::getContactStatus(MCONTACT hContact) -{ - return getWord(hContact, "Status", ID_STATUS_OFFLINE); -} - -int CIcqProto::getSettingStringStatic(MCONTACT hContact, const char *szSetting, char *dest, size_t dest_len) -{ - if (!db_get_static(hContact, m_szModuleName, szSetting, dest, (int)dest_len)) - return 0; - - return db_get_static_utf(hContact, m_szModuleName, szSetting, dest, (int)dest_len); -} - -int CIcqProto::setSettingDouble(MCONTACT hContact, const char *szSetting, double dValue) -{ - return setSettingBlob(hContact, szSetting, (BYTE*)&dValue, sizeof(double)); -} - -int CIcqProto::setSettingBlob(MCONTACT hContact, const char *szSetting, const BYTE *pValue, size_t cbValue) -{ - return db_set_blob(hContact, m_szModuleName, szSetting, (void*)pValue, (unsigned)cbValue); -} - -int CIcqProto::setContactHidden(MCONTACT hContact, BYTE bHidden) -{ - int nResult = db_set_b(hContact, "CList", "Hidden", bHidden); - if (!bHidden) // clear zero setting - db_unset(hContact, "CList", "Hidden"); - - return nResult; -} - -void CIcqProto::setStatusMsgVar(MCONTACT hContact, char* szStatusMsg, bool isAnsi) -{ - if (szStatusMsg && szStatusMsg[0]) { - if (isAnsi) { - char *szStatusNote = getSettingStringUtf(hContact, DBSETTING_STATUS_NOTE, ""); - wchar_t *szStatusNoteW = make_unicode_string(szStatusNote); - int len = (int)mir_wstrlen(szStatusNoteW) * 3 + 1; - char *szStatusNoteAnsi = (char*)alloca(len); - WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, szStatusNoteW, -1, szStatusNoteAnsi, len, nullptr, nullptr); - bool notmatch = false; - for (int i = 0;; ++i) { - if (szStatusNoteAnsi[i] != szStatusMsg[i] && szStatusNoteAnsi[i] != '?' && szStatusMsg[i] != '?') { - notmatch = true; - break; - } - if (!szStatusNoteAnsi[i] || !szStatusMsg[i]) - break; - } - szStatusMsg = notmatch ? ansi_to_utf8(szStatusMsg) : szStatusNote; - SAFE_FREE(&szStatusNoteW); - if (notmatch) - SAFE_FREE(&szStatusNote); - } - - char *oldStatusMsg = nullptr; - DBVARIANT dbv; - if (!db_get_ws(hContact, "CList", "StatusMsg", &dbv)) { - oldStatusMsg = make_utf8_string(dbv.pwszVal); - db_free(&dbv); - } - - if (!oldStatusMsg || mir_strcmp(oldStatusMsg, szStatusMsg)) - db_set_utf(hContact, "CList", "StatusMsg", szStatusMsg); - SAFE_FREE(&oldStatusMsg); - if (isAnsi) SAFE_FREE(&szStatusMsg); - } - else db_unset(hContact, "CList", "StatusMsg"); -} - -int CIcqProto::IsICQContact(MCONTACT hContact) -{ - char* szProto = GetContactProto(hContact); - - return !mir_strcmp(szProto, m_szModuleName); -} - -MEVENT CIcqProto::AddEvent(MCONTACT hContact, WORD wType, DWORD dwTime, DWORD flags, size_t cbBlob, PBYTE pBlob) -{ - DBEVENTINFO dbei = {}; - dbei.szModule = m_szModuleName; - dbei.timestamp = dwTime; - dbei.flags = flags; - dbei.eventType = wType; - dbei.cbBlob = (DWORD)cbBlob; - dbei.pBlob = pBlob; - return db_event_add(hContact, &dbei); -} - -char* CIcqProto::getContactCListGroup(MCONTACT hContact) -{ - return getSettingStringUtf(hContact, "CList", "Group", nullptr); -} diff --git a/protocols/IcqOscarJ/src/icq_direct.cpp b/protocols/IcqOscarJ/src/icq_direct.cpp deleted file mode 100644 index 00d3fc61d4..0000000000 --- a/protocols/IcqOscarJ/src/icq_direct.cpp +++ /dev/null @@ -1,946 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -struct directthreadstartinfo -{ - int type; // Only valid for outgoing connections - int incoming; // 1=incoming, 0=outgoing - HNETLIBCONN hConnection; // only valid for incoming connections, handle to the connection - MCONTACT hContact; // Only valid for outgoing connections - void* pvExtra; // Only valid for outgoing connections -}; - -static char client_check_data[] = { - "As part of this software beta version Mirabilis is " - "granting a limited access to the ICQ network, " - "servers, directories, listings, information and databases (\"" - "ICQ Services and Information\"). The " - "ICQ Service and Information may databases (\"" - "ICQ Services and Information\"). The " - "ICQ Service and Information may\0" -}; - -void CIcqProto::CloseContactDirectConns(MCONTACT hContact) -{ - mir_cslock l(directConnListMutex); - - for (auto &it : directConns) { - if (!hContact || it->hContact == hContact) { - HNETLIBCONN hConnection = it->hConnection; - - it->hConnection = nullptr; // do not allow reuse - NetLib_CloseConnection(&hConnection, FALSE); - } - } -} - - -directconnect* CIcqProto::FindFileTransferDC(filetransfer* ft) -{ - mir_cslock l(directConnListMutex); - - for (auto &it : directConns) - if (it->ft == ft) - return it; - - return nullptr; -} - - -filetransfer* CIcqProto::FindExpectedFileRecv(DWORD dwUin, DWORD dwTotalSize) -{ - mir_cslock l(expectedFileRecvMutex); - - for (auto &it : expectedFileRecvs) - if (it->dwUin == dwUin && it->dwTotalSize == dwTotalSize) - return expectedFileRecvs.removeItem(&it); - - return nullptr; -} - - -int CIcqProto::sendDirectPacket(directconnect* dc, icq_packet* pkt) -{ - int nResult = Netlib_Send(dc->hConnection, (const char*)pkt->pData, pkt->wLen + 2, 0); - if (nResult == SOCKET_ERROR) { - NetLog_Direct("Direct %p socket error: %d, closing", dc->hConnection, GetLastError()); - CloseDirectConnection(dc); - } - - SAFE_FREE((void**)&pkt->pData); - - return nResult; -} - -directthreadstartinfo* CreateDTSI(MCONTACT hContact, HNETLIBCONN hConnection, int type) -{ - directthreadstartinfo *dtsi = (directthreadstartinfo*)SAFE_MALLOC(sizeof(directthreadstartinfo)); - dtsi->hContact = hContact; - dtsi->hConnection = hConnection; - if (type == -1) - dtsi->incoming = 1; - else - dtsi->type = type; - - return dtsi; -} - -// Check if we have an open and initialized DC with type -// 'type' to the specified contact -BOOL CIcqProto::IsDirectConnectionOpen(MCONTACT hContact, int type, int bPassive) -{ - BOOL bIsOpen = FALSE, bIsCreated = FALSE; - { - mir_cslock l(directConnListMutex); - - for (auto &it : directConns) { - if (it && it->type == type) { - if (it->hContact == hContact) { - if (it->initialised) { - // Connection is OK - bIsOpen = TRUE; - // we are going to use the conn, so prevent timeout - it->packetPending = 1; - break; - } - else bIsCreated = TRUE; // we found pending connection - } - } - } - } - - if (!bPassive && !bIsCreated && !bIsOpen && type == DIRECTCONN_STANDARD && m_bDCMsgEnabled == 2) { // do not try to open DC to offline contact - if (getContactStatus(hContact) == ID_STATUS_OFFLINE) return FALSE; - // do not try to open DC if previous attempt was not successfull - if (getByte(hContact, "DCStatus", 0)) return FALSE; - - // Set DC status as tried - setByte(hContact, "DCStatus", 1); - // Create a new connection - OpenDirectConnection(hContact, DIRECTCONN_STANDARD, nullptr); - } - - return bIsOpen; -} - -// This function is called from the Netlib when someone is connecting to -// one of our incomming DC ports -void icq_newConnectionReceived(HNETLIBCONN hNewConnection, DWORD, void *pExtra) -{ - // Start a new thread for the incomming connection - CIcqProto* ppro = (CIcqProto*)pExtra; - ppro->ForkThread((CIcqProto::MyThreadFunc)&CIcqProto::icq_directThread, CreateDTSI(NULL, hNewConnection, -1)); -} - -// Opens direct connection of specified type to specified contact -void CIcqProto::OpenDirectConnection(MCONTACT hContact, int type, void* pvExtra) -{ - // Create a new connection - directthreadstartinfo* dtsi = CreateDTSI(hContact, nullptr, type); - dtsi->pvExtra = pvExtra; - ForkThread((MyThreadFunc)&CIcqProto::icq_directThread, dtsi); -} - -// Safely close NetLib connection - do not corrupt direct connection list -void CIcqProto::CloseDirectConnection(directconnect *dc) -{ - mir_cslock l(directConnListMutex); - - NetLib_CloseConnection(&dc->hConnection, FALSE); - - if (dc->hConnection) - NetLog_Direct("Direct conn closed (%p)", dc->hConnection); -} - -// Called from icq_newConnectionReceived when a new incomming dc is done -// Called from OpenDirectConnection when a new outgoing dc is done -// Called from SendDirectMessage when a new outgoing dc is done - -void __cdecl CIcqProto::icq_directThread(directthreadstartinfo *dtsi) -{ - Thread_SetName("ICQ: directThread"); - - NETLIBPACKETRECVER packetRecv = {}; - directconnect dc = { 0 }; - BOOL bFirstPacket = TRUE; - size_t nSkipPacketBytes = 0; - DWORD dwReqMsgID1 = 0, dwReqMsgID2 = 0; - - srand(time(0)); - { - // add to DC connection list - mir_cslock l(directConnListMutex); - directConns.insert(&dc); - } - - // Initialize DC struct - dc.hContact = dtsi->hContact; - dc.dwThreadId = GetCurrentThreadId(); - dc.incoming = dtsi->incoming; - dc.hConnection = dtsi->hConnection; - dc.ft = nullptr; - - if (!dc.incoming) { - dc.type = dtsi->type; - dc.dwRemoteExternalIP = getDword(dtsi->hContact, "IP", 0); - dc.dwRemoteInternalIP = getDword(dtsi->hContact, "RealIP", 0); - dc.dwRemotePort = getWord(dtsi->hContact, "UserPort", 0); - dc.dwRemoteUin = getContactUin(dtsi->hContact); - dc.dwConnectionCookie = getDword(dtsi->hContact, "DirectCookie", 0); - dc.wVersion = getWord(dtsi->hContact, "Version", 0); - - if (!dc.dwRemoteExternalIP && !dc.dwRemoteInternalIP) { // we do not have any ip, do not try to connect - SAFE_FREE((void**)&dtsi); - goto LBL_Exit; - } - if (!dc.dwRemotePort) { // we do not have port, do not try to connect - SAFE_FREE((void**)&dtsi); - goto LBL_Exit; - } - - if (dc.type == DIRECTCONN_STANDARD) { - // do nothing - some specific init for msg sessions - } - else if (dc.type == DIRECTCONN_FILE) { - dc.ft = (filetransfer*)dtsi->pvExtra; - dc.dwRemotePort = dc.ft->dwRemotePort; - } - else if (dc.type == DIRECTCONN_REVERSE) { - cookie_reverse_connect *pCookie = (cookie_reverse_connect*)dtsi->pvExtra; - - dwReqMsgID1 = pCookie->dwMsgID1; - dwReqMsgID2 = pCookie->dwMsgID2; - dc.dwReqId = (UINT_PTR)pCookie->ft; - SAFE_FREE((void**)&pCookie); - } - } - else dc.type = DIRECTCONN_STANDARD; - - SAFE_FREE((void**)&dtsi); - - // Load local IP information - dc.dwLocalExternalIP = getDword("IP", 0); - dc.dwLocalInternalIP = getDword("RealIP", 0); - - // Create outgoing DC - if (!dc.incoming) { - NETLIBOPENCONNECTION nloc = { 0 }; - IN_ADDR addr = { 0 }, addr2 = { 0 }; - - if (dc.dwRemoteExternalIP == dc.dwLocalExternalIP && dc.dwRemoteInternalIP) - addr.S_un.S_addr = htonl(dc.dwRemoteInternalIP); - else { - addr.S_un.S_addr = htonl(dc.dwRemoteExternalIP); - // for different internal, try it also (for LANs with multiple external IP, VPNs, etc.) - if (dc.dwRemoteInternalIP != dc.dwRemoteExternalIP) - addr2.S_un.S_addr = htonl(dc.dwRemoteInternalIP); - } - - // IP to connect to is empty, go away - if (!addr.S_un.S_addr) - goto LBL_Exit; - - nloc.szHost = inet_ntoa(addr); - nloc.wPort = (WORD)dc.dwRemotePort; - nloc.timeout = 8; // 8 secs to connect - dc.hConnection = NetLib_OpenConnection(m_hDirectNetlibUser, dc.type == DIRECTCONN_REVERSE ? "Reverse " : nullptr, &nloc); - if (!dc.hConnection && addr2.S_un.S_addr) { // first address failed, try second one if available - nloc.szHost = inet_ntoa(addr2); - dc.hConnection = NetLib_OpenConnection(m_hDirectNetlibUser, dc.type == DIRECTCONN_REVERSE ? "Reverse " : nullptr, &nloc); - } - if (!dc.hConnection) { - if (CheckContactCapabilities(dc.hContact, CAPF_ICQDIRECT)) { // only if the contact support ICQ DC connections - if (dc.type != DIRECTCONN_REVERSE) { // try reverse connect - cookie_reverse_connect *pCookie = (cookie_reverse_connect*)SAFE_MALLOC(sizeof(cookie_reverse_connect)); - DWORD dwCookie; - - NetLog_Direct("connect() failed (%d), trying reverse.", GetLastError()); - - if (pCookie) { // init cookie - InitMessageCookie(pCookie); - pCookie->bMessageType = MTYPE_REVERSE_REQUEST; - pCookie->hContact = dc.hContact; - pCookie->dwUin = dc.dwRemoteUin; - pCookie->type = dc.type; - pCookie->ft = dc.ft; - dwCookie = AllocateCookie(CKT_REVERSEDIRECT, 0, dc.hContact, pCookie); - icq_sendReverseReq(&dc, dwCookie, (cookie_message_data*)pCookie); - goto LBL_Exit; - } - - NetLog_Direct("Reverse failed (%s)", "malloc failed"); - } - } - else // Set DC status to failed - setByte(dc.hContact, "DCStatus", 2); - - if (dc.type == DIRECTCONN_REVERSE) // failed reverse connection - icq_sendReverseFailed(&dc, dwReqMsgID1, dwReqMsgID2, dc.dwReqId); - - NetLog_Direct("connect() failed (%d)", GetLastError()); - if (dc.type == DIRECTCONN_FILE) { - ProtoBroadcastAck(dc.ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, dc.ft, 0); - // Release transfer - SafeReleaseFileTransfer((basic_filetransfer**)&dc.ft); - } - goto LBL_Exit; - } - - if (dc.type == DIRECTCONN_FILE) - dc.ft->hConnection = dc.hConnection; - - if (dc.wVersion > 6) - sendPeerInit_v78(&dc); - else { - NetLog_Direct("Error: Unsupported direct protocol: %d, closing.", dc.wVersion); - CloseDirectConnection(&dc); - goto LBL_Exit; - } - } - - HANDLE hPacketRecver = Netlib_CreatePacketReceiver(dc.hConnection, 8192); - - // Packet receiving loop - - while (dc.hConnection) { - packetRecv.dwTimeout = dc.wantIdleTime ? 0 : 600000; - - int recvResult = Netlib_GetMorePackets(hPacketRecver, &packetRecv); - if (recvResult == 0) { - NetLog_Direct("Clean closure of direct socket (%p)", dc.hConnection); - break; - } - - if (recvResult == SOCKET_ERROR) { - if (GetLastError() == ERROR_TIMEOUT) { // TODO: this will not work on some systems - if (dc.wantIdleTime) { - switch (dc.type) { - case DIRECTCONN_FILE: - handleFileTransferIdle(&dc); - break; - } - } - else if (dc.packetPending) { // do we expect packet soon? - NetLog_Direct("Keeping connection, packet pending."); - } - else { - NetLog_Direct("Connection inactive for 10 minutes, closing."); - break; - } - } - else { - NetLog_Direct("Abortive closure of direct socket (%p) (%d)", dc.hConnection, GetLastError()); - break; - } - } - - if (dc.type == DIRECTCONN_CLOSING) - packetRecv.bytesUsed = packetRecv.bytesAvailable; - else if (packetRecv.bytesAvailable < (int)nSkipPacketBytes) { // the whole buffer needs to be skipped - nSkipPacketBytes -= packetRecv.bytesAvailable; - packetRecv.bytesUsed = packetRecv.bytesAvailable; - } - else { - size_t i; - for (i = nSkipPacketBytes, nSkipPacketBytes = 0; (int)i + 2 <= packetRecv.bytesAvailable;) { - size_t wLen = *(WORD*)(packetRecv.buffer + i); - - if (bFirstPacket) { - if (wLen > 64) { // roughly check first packet size - NetLog_Direct("Error: Overflowed packet, closing connection."); - CloseDirectConnection(&dc); - break; - } - bFirstPacket = FALSE; - } - else if (packetRecv.bytesAvailable >= (int)i + 2 && wLen > 8190) { // check for too big packages - NetLog_Direct("Error: Package too big: %d bytes, skipping."); - nSkipPacketBytes = wLen; - packetRecv.bytesUsed = int(i + 2); - break; - } - - if (wLen + 2 + i > (size_t)packetRecv.bytesAvailable) - break; - - if (dc.type == DIRECTCONN_STANDARD && wLen && packetRecv.buffer[i + 2] == 2) { - if (!DecryptDirectPacket(&dc, packetRecv.buffer + i + 3, wLen - 1)) { - NetLog_Direct("Error: Corrupted packet encryption, ignoring packet"); - i += wLen + 2; - continue; - } - } - - if (dc.type == DIRECTCONN_FILE && dc.initialised) - handleFileTransferPacket(&dc, packetRecv.buffer + i + 2, wLen); - else - handleDirectPacket(&dc, packetRecv.buffer + i + 2, wLen); - - i += wLen + 2; - } - packetRecv.bytesUsed = (int)i; - } - } - - // End of packet receiving loop - NetLib_SafeCloseHandle(&hPacketRecver); - CloseDirectConnection(&dc); - - if (dc.ft) { - if (dc.ft->fileId != -1) { - _close(dc.ft->fileId); - ProtoBroadcastAck(dc.ft->hContact, ACKTYPE_FILE, dc.ft->dwBytesDone == dc.ft->dwTotalSize ? ACKRESULT_SUCCESS : ACKRESULT_FAILED, dc.ft, 0); - } - else if (dc.ft->hConnection) - ProtoBroadcastAck(dc.ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, dc.ft, 0); - - SafeReleaseFileTransfer((basic_filetransfer**)&dc.ft); - _chdir("\\"); /* so we don't leave a subdir handle open so it can't be deleted */ - } - -LBL_Exit: - // remove from DC connection list - mir_cslock l(directConnListMutex); - directConns.remove(&dc); -} - -void CIcqProto::handleDirectPacket(directconnect* dc, PBYTE buf, size_t wLen) -{ - if (wLen < 1) - return; - - switch (buf[0]) { - case PEER_FILE_INIT: // first packet of a file transfer - NetLog_Direct("Received PEER_FILE_INIT from %u", dc->dwRemoteUin); - - if (dc->handshake) - handleFileTransferPacket(dc, buf, wLen); - else - NetLog_Direct("Received %s on uninitialised DC, ignoring.", "PEER_FILE_INIT"); - - break; - - case PEER_INIT_ACK: // This is sent as a response to our PEER_INIT packet - if (wLen != 4) { - NetLog_Direct("Error: Received malformed PEER_INITACK from %u", dc->dwRemoteUin); - break; - } - - NetLog_Direct("Received PEER_INITACK from %u on %s DC", dc->dwRemoteUin, dc->incoming ? "incoming" : "outgoing"); - - if (dc->incoming) dc->handshake = 1; - - if (dc->incoming && dc->type == DIRECTCONN_REVERSE) { - dc->incoming = 0; - - cookie_reverse_connect *pCookie; - if (FindCookie(dc->dwReqId, nullptr, (void**)&pCookie) && pCookie) { // valid reverse DC, check and init session - FreeCookie(dc->dwReqId); - if (pCookie->dwUin == dc->dwRemoteUin) { // valid connection - dc->type = pCookie->type; - dc->ft = (filetransfer*)pCookie->ft; - dc->hContact = pCookie->hContact; - if (dc->type == DIRECTCONN_STANDARD) { // init message session - sendPeerMsgInit(dc, 0); - } - else if (dc->type == DIRECTCONN_FILE) { // init file session - sendPeerFileInit(dc); - dc->initialised = 1; - } - SAFE_FREE((void**)&pCookie); - break; - } - else { - SAFE_FREE((void**)&pCookie); - NetLog_Direct("Error: Invalid connection (UINs does not match)."); - CloseDirectConnection(dc); - return; - } - } - else { - NetLog_Direct("Error: Received unexpected reverse DC, closing."); - CloseDirectConnection(dc); - return; - } - } - break; - - case PEER_INIT: /* connect packet */ - NetLog_Direct("Received PEER_INIT"); - - buf++; - - if (wLen < 3) - return; - - unpackLEWord(&buf, &dc->wVersion); - - if (dc->wVersion > 6) { // we support only versions 7 and up - DWORD dwUin; - DWORD dwPort; - DWORD dwCookie; - MCONTACT hContact = 0; - - if (wLen != 0x30) { - NetLog_Direct("Error: Received malformed PEER_INIT"); - return; - } - - size_t wSecondLen; - unpackLEWord(&buf, &wSecondLen); - if (wSecondLen && wSecondLen != 0x2b) { // OMG? GnomeICU sets this to zero - NetLog_Direct("Error: Received malformed PEER_INIT"); - return; - } - - unpackLEDWord(&buf, &dwUin); - if (dwUin != m_dwLocalUIN) { - NetLog_Direct("Error: Received PEER_INIT targeted to %u", dwUin); - CloseDirectConnection(dc); - return; - } - - buf += 2; /* 00 00 */ - unpackLEDWord(&buf, &dc->dwRemotePort); - unpackLEDWord(&buf, &dc->dwRemoteUin); - unpackDWord(&buf, &dc->dwRemoteExternalIP); - unpackDWord(&buf, &dc->dwRemoteInternalIP); - buf++; /* 04: accept direct connections */ - unpackLEDWord(&buf, &dwPort); - if (dwPort != dc->dwRemotePort) { - NetLog_Direct("Error: Received malformed PEER_INIT (invalid port)"); - return; - } - unpackLEDWord(&buf, &dwCookie); - - buf += 8; // Unknown stuff - unpackLEDWord(&buf, &dc->dwReqId); - - if (dc->dwRemoteUin || !dc->dwReqId) { // OMG! Licq sends on reverse connection empty uin - hContact = HContactFromUIN(dc->dwRemoteUin, nullptr); - if (hContact == INVALID_CONTACT_ID) { - NetLog_Direct("Error: Received PEER_INIT from %u not on my list", dwUin); - CloseDirectConnection(dc); - return; /* don't allow direct connection with people not on my clist */ - } - - if (dc->incoming) { // this is the first PEER_INIT with our cookie - if (dwCookie != getDword(hContact, "DirectCookie", 0)) { - NetLog_Direct("Error: Received PEER_INIT with broken cookie"); - CloseDirectConnection(dc); - return; - } - } - else { // this is the second PEER_INIT with peer cookie - if (dwCookie != dc->dwConnectionCookie) { - NetLog_Direct("Error: Received PEER_INIT with broken cookie"); - CloseDirectConnection(dc); - return; - } - } - } - - if (dc->incoming && dc->dwReqId) { // this is reverse connection - dc->type = DIRECTCONN_REVERSE; - if (!dc->dwRemoteUin) { // we need to load cookie (licq) - cookie_reverse_connect *pCookie; - - if (FindCookie(dc->dwReqId, nullptr, (void**)&pCookie) && pCookie) { // valid reverse DC, check and init session - dc->dwRemoteUin = pCookie->dwUin; - dc->hContact = pCookie->hContact; - } - else { - NetLog_Direct("Error: Received unexpected reverse DC, closing."); - CloseDirectConnection(dc); - return; - } - } - } - - sendPeerInitAck(dc); // ack good PEER_INIT packet - - if (dc->incoming) { // store good IP info - dc->hContact = hContact; - dc->dwConnectionCookie = dwCookie; - setDword(dc->hContact, "IP", dc->dwRemoteExternalIP); - setDword(dc->hContact, "RealIP", dc->dwRemoteInternalIP); - sendPeerInit_v78(dc); // reply with our PEER_INIT - } - else { // outgoing - dc->handshake = 1; - - if (dc->type == DIRECTCONN_REVERSE) { - dc->incoming = 1; // this is incoming reverse connection - dc->type = DIRECTCONN_STANDARD; // we still do not know type - } - else if (dc->type == DIRECTCONN_STANDARD) { // send PEER_MSGINIT - sendPeerMsgInit(dc, 0); - } - else if (dc->type == DIRECTCONN_FILE) { - sendPeerFileInit(dc); - dc->initialised = 1; - } - } - // Set DC Status to successful - setByte(dc->hContact, "DCStatus", 0); - } - else { - NetLog_Direct("Unsupported direct protocol: %d, closing connection", dc->wVersion); - CloseDirectConnection(dc); - } - break; - - case PEER_MSG: /* messaging packets */ - NetLog_Direct("Received PEER_MSG from %u", dc->dwRemoteUin); - - if (dc->initialised) - handleDirectMessage(dc, buf + 1, wLen - 1); - else - NetLog_Direct("Received %s on uninitialised DC, ignoring.", "PEER_MSG"); - - break; - - case PEER_MSG_INIT: /* init message connection */ - // it is sent by both contains GUID of message channel - if (!m_bDCMsgEnabled) { // DC messaging disabled, close connection - NetLog_Direct("Messaging DC requested, denied"); - CloseDirectConnection(dc); - break; - } - - NetLog_Direct("Received PEER_MSG_INIT from %u", dc->dwRemoteUin); - - buf++; - if (wLen != 0x21) - break; - - if (!dc->handshake) { - NetLog_Direct("Received %s on unitialised DC, ignoring.", "PEER_MSG_INIT"); - break; - } - { - DWORD q1, q2, q3, q4; - - buf += 4; /* always 10 */ - buf += 4; /* some id */ - buf += 4; /* sequence - always 0 on incoming */ - unpackDWord(&buf, &q1); // session type GUID - unpackDWord(&buf, &q2); - if (!dc->incoming) // skip marker on sequence 1 - buf += 4; - - unpackDWord(&buf, &q3); - unpackDWord(&buf, &q4); - if (!CompareGUIDs(q1, q2, q3, q4, PSIG_MESSAGE)) { // This is not for normal messages, useless so kill. - if (CompareGUIDs(q1, q2, q3, q4, PSIG_STATUS_PLUGIN)) - NetLog_Direct("Status Manager Plugin connections not supported, closing."); - else if (CompareGUIDs(q1, q2, q3, q4, PSIG_INFO_PLUGIN)) - NetLog_Direct("Info Manager Plugin connection not supported, closing."); - else - NetLog_Direct("Unknown connection type init, closing."); - - CloseDirectConnection(dc); - break; - } - } - - if (dc->incoming) // reply with our PEER_MSG_INIT - sendPeerMsgInit(dc, 1); - - NetLog_Direct("Direct message session ready."); - dc->initialised = 1; - break; - - default: - NetLog_Direct("Unknown direct packet ignored."); - break; - } -} - -void EncryptDirectPacket(directconnect* dc, icq_packet* p) -{ - unsigned long B1; - unsigned long M1; - unsigned long check; - unsigned int i; - unsigned char X1; - unsigned char X2; - unsigned char X3; - unsigned char* buf = (unsigned char*)(p->pData + 3); - unsigned char bak[6]; - unsigned long offset; - unsigned long key; - unsigned long hex; - unsigned long size = p->wLen - 1; - - if (dc->wVersion < 4) - return; // no encryption necessary. - - switch (dc->wVersion) { - case 4: - case 5: - offset = 6; - break; - - default: - offset = 0; - } - - // calculate verification data - M1 = (rand() % ((size < 255 ? size : 255) - 10)) + 10; - X1 = buf[M1] ^ 0xFF; - X2 = rand() % 220; - X3 = client_check_data[X2] ^ 0xFF; - if (offset) { - memcpy(bak, buf, sizeof(bak)); - B1 = (buf[offset + 4] << 24) | (buf[offset + 6] << 16) | (buf[2] << 8) | buf[0]; - } - else B1 = (buf[4] << 24) | (buf[6] << 16) | (buf[4] << 8) | (buf[6]); - - // calculate checkcode - check = (M1 << 24) | (X1 << 16) | (X2 << 8) | X3; - check ^= B1; - - // main XOR key - key = 0x67657268 * size + check; - - // XORing the actual data - for (i = 0; i < (size + 3) / 4; i += 4) { - hex = key + client_check_data[i & 0xFF]; - *(PDWORD)(buf + i) ^= hex; - } - - // in TCPv4 are the first 6 bytes unencrypted - // so restore them - if (offset) - memcpy(buf, bak, sizeof(bak)); - - // storing the checkcode - *(PDWORD)(buf + offset) = check; -} - -int DecryptDirectPacket(directconnect* dc, PBYTE buf, size_t wLen) -{ - unsigned long hex; - unsigned long B1; - unsigned long M1; - unsigned int i; - unsigned char X1; - unsigned char X2; - unsigned char X3; - unsigned char bak[6]; - unsigned long size = (unsigned long)wLen; - - if (dc->wVersion < 4) - return 1; // no decryption necessary. - - if (size < 4) - return 1; - - // backup the first 6 bytes - unsigned long offset = (dc->wVersion == 4 || dc->wVersion == 5) ? 6 : 0; - if (offset) - memcpy(bak, buf, sizeof(bak)); - - // retrieve checkcode - unsigned long check = *(PDWORD)(buf + offset); - - // main XOR key - unsigned long key = 0x67657268 * size + check; - - for (i = 4; i < (size + 3) / 4; i += 4) { - hex = key + client_check_data[i & 0xFF]; - *(PDWORD)(buf + i) ^= hex; - } - - // retrive validate data - if (offset) { - // in TCPv4 are the first 6 bytes unencrypted - // so restore them - memcpy(buf, bak, sizeof(bak)); - B1 = (buf[offset + 4] << 24) | (buf[offset + 6] << 16) | (buf[2] << 8) | buf[0]; - } - else B1 = (buf[4] << 24) | (buf[6] << 16) | (buf[4] << 8) | (buf[6] << 0); - - // special decryption - B1 ^= check; - - // validate packet - M1 = (B1 >> 24) & 0xFF; - if (M1 < 10 || M1 >= size) - return 0; - - X1 = buf[M1] ^ 0xFF; - if (((B1 >> 16) & 0xFF) != X1) - return 0; - - X2 = (BYTE)((B1 >> 8) & 0xFF); - if (X2 < 220) { - X3 = client_check_data[X2] ^ 0xFF; - if ((B1 & 0xFF) != X3) - return 0; - } - - return 1; -} - -// This should be called only if connection already exists -int CIcqProto::SendDirectMessage(MCONTACT hContact, icq_packet *pkt) -{ - mir_cslock l(directConnListMutex); - - for (auto &it : directConns) { - if (it == nullptr) - continue; - - if (it->hContact == hContact) { - if (it->initialised) { - // This connection can be reused, send packet and exit - NetLog_Direct("Sending direct message"); - - if (pkt->pData[2] == 2) - EncryptDirectPacket(it, pkt); - - sendDirectPacket(it, pkt); - it->packetPending = 0; // packet done - - return TRUE; // Success - } - break; // connection not ready, use server instead - } - } - - return FALSE; // connection pending, we failed, use server instead -} - -// Sends a PEER_INIT packet through a DC -// ----------------------------------------------------------------------- -// This packet is sent during direct connection initialization between two -// ICQ clients. It is sent by the originator of the connection to start -// the handshake and by the receiver directly after it has sent the -// PEER_ACK packet as a reply to the originator's PEER_INIT. The values -// after the COOKIE field have been added for v7. - -void CIcqProto::sendPeerInit_v78(directconnect* dc) -{ - icq_packet packet; - directPacketInit(&packet, 48); - - packByte(&packet, PEER_INIT); // Command - packLEWord(&packet, dc->wVersion); // Version - packLEWord(&packet, 43); // Data length - packLEDWord(&packet, dc->dwRemoteUin); // UIN of remote user - packWord(&packet, 0); // Unknown - packLEDWord(&packet, wListenPort); // Our port - packLEDWord(&packet, m_dwLocalUIN); // Our UIN - packDWord(&packet, dc->dwLocalExternalIP); // Our external IP - packDWord(&packet, dc->dwLocalInternalIP); // Our internal IP - packByte(&packet, DC_TYPE); // TCP connection flags - packLEDWord(&packet, wListenPort); // Our port - packLEDWord(&packet, dc->dwConnectionCookie); // DC cookie - packLEDWord(&packet, WEBFRONTPORT); // Unknown - packLEDWord(&packet, CLIENTFEATURES); // Unknown - if (dc->type == DIRECTCONN_REVERSE) - packLEDWord(&packet, dc->dwReqId); // Reverse Request Cookie - else - packDWord(&packet, 0); // Unknown - - sendDirectPacket(dc, &packet); - - NetLog_Direct("Sent PEER_INIT to %u on %s DC", dc->dwRemoteUin, dc->incoming ? "incoming" : "outgoing"); -} - -// Sends a PEER_INIT packet through a DC -// ----------------------------------------------------------------------- -// This is sent to acknowledge a PEER_INIT packet. - -void CIcqProto::sendPeerInitAck(directconnect* dc) -{ - icq_packet packet; - directPacketInit(&packet, 4); // Packet length - packLEDWord(&packet, PEER_INIT_ACK); // - - sendDirectPacket(dc, &packet); - - NetLog_Direct("Sent PEER_INIT_ACK to %u on %s DC", dc->dwRemoteUin, dc->incoming ? "incoming" : "outgoing"); -} - -// Sends a PEER_MSG_INIT packet through a DC -// ----------------------------------------------------------------------- -// This packet starts message session. - -void CIcqProto::sendPeerMsgInit(directconnect* dc, DWORD dwSeq) -{ - icq_packet packet; - directPacketInit(&packet, 33); - - packByte(&packet, PEER_MSG_INIT); - packLEDWord(&packet, 10); // unknown - packLEDWord(&packet, 1); // message connection - packLEDWord(&packet, dwSeq); // sequence is 0,1 - if (!dwSeq) { - packGUID(&packet, PSIG_MESSAGE); // message type GUID - packLEWord(&packet, 1); // delimiter - packLEWord(&packet, 4); - } - else { - packDWord(&packet, 0); // first part of Message GUID - packDWord(&packet, 0); - packLEWord(&packet, 1); // delimiter - packLEWord(&packet, 4); - packDWord(&packet, 0); // second part of Message GUID - packDWord(&packet, 0); - } - sendDirectPacket(dc, &packet); - - NetLog_Direct("Sent PEER_MSG_INIT to %u on %s DC", dc->dwRemoteUin, dc->incoming ? "incoming" : "outgoing"); -} - -// Sends a PEER_FILE_INIT packet through a DC -// ----------------------------------------------------------------------- -// This packet configures file-transfer session. - -void CIcqProto::sendPeerFileInit(directconnect* dc) -{ - ptrA tmp(getStringA("Nick")); - char *szNick = NEWSTR_ALLOCA((tmp == NULL) ? "" : tmp); - size_t nNickLen = mir_strlen(szNick); - - icq_packet packet; - directPacketInit(&packet, 20 + nNickLen); - - packByte(&packet, PEER_FILE_INIT); /* packet type */ - packLEDWord(&packet, 0); /* unknown */ - packLEDWord(&packet, dc->ft->dwFileCount); - packLEDWord(&packet, dc->ft->dwTotalSize); - packLEDWord(&packet, dc->ft->dwTransferSpeed); - packLEWord(&packet, WORD(nNickLen + 1)); - packBuffer(&packet, (LPBYTE)szNick, nNickLen + 1); - sendDirectPacket(dc, &packet); - - NetLog_Direct("Sent PEER_FILE_INIT to %u on %s DC", dc->dwRemoteUin, dc->incoming ? "incoming" : "outgoing"); -} diff --git a/protocols/IcqOscarJ/src/icq_direct.h b/protocols/IcqOscarJ/src/icq_direct.h deleted file mode 100644 index b3780596e9..0000000000 --- a/protocols/IcqOscarJ/src/icq_direct.h +++ /dev/null @@ -1,87 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2009 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// ----------------------------------------------------------------------------- - -#ifndef __ICQ_DIRECT_H -#define __ICQ_DIRECT_H - -struct filetransfer : public basic_filetransfer -{ - int status; - int sending; - int currentIsDir; - DWORD dwUin; - DWORD dwRemotePort; - char *szFilename; - char *szDescription; - char *szSavePath; - char *szThisFile; - char *szThisSubdir; - char **pszFiles; - DWORD dwThisFileSize; - DWORD dwThisFileDate; - DWORD dwTotalSize; - DWORD dwFileCount; - DWORD dwTransferSpeed; - DWORD dwBytesDone, dwFileBytesDone; - int fileId; - HNETLIBCONN hConnection; - DWORD dwLastNotify; - int nVersion; // Was this sent with a v7 or a v8 packet? - BOOL bDC; // Was this received over a DC or through server? - BOOL bEmptyDesc; // Was the description empty ? -}; - -#define DIRECTCONN_STANDARD 0 -#define DIRECTCONN_FILE 1 -#define DIRECTCONN_CHAT 2 -#define DIRECTCONN_REVERSE 10 -#define DIRECTCONN_CLOSING 15 - -struct directconnect -{ - MCONTACT hContact; - HNETLIBCONN hConnection; - DWORD dwConnectionCookie; - int type; - WORD wVersion; - int incoming; - int wantIdleTime; - int packetPending; - DWORD dwRemotePort; - DWORD dwRemoteUin; - DWORD dwRemoteExternalIP; - DWORD dwRemoteInternalIP; - DWORD dwLocalExternalIP; - DWORD dwLocalInternalIP; - int initialised; - int handshake; - DWORD dwThreadId; - filetransfer *ft; - DWORD dwReqId; // Reverse Connect request cookie -}; - -int DecryptDirectPacket(directconnect *dc, PBYTE buf, size_t wLen); - -#endif /* __ICQ_DIRECT_H */ diff --git a/protocols/IcqOscarJ/src/icq_directmsg.cpp b/protocols/IcqOscarJ/src/icq_directmsg.cpp deleted file mode 100644 index ca7925b89c..0000000000 --- a/protocols/IcqOscarJ/src/icq_directmsg.cpp +++ /dev/null @@ -1,313 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -void CIcqProto::handleDirectMessage(directconnect* dc, PBYTE buf, size_t wLen) -{ - WORD wCommand; - WORD wCookie; - BYTE bMsgType, bMsgFlags; - WORD wStatus; - WORD wFlags; - WORD wTextLen; - char* pszText = nullptr; - - // The first part of the packet should always be at least 31 bytes - if (wLen < 31) { - NetLog_Direct("Error during parsing of DC packet 2 PEER_MSG (too short)"); - return; - } - - // Skip packet checksum - buf += 4; - wLen -= 4; - - // Command: - // 0x07d0 = 2000 - cancel given message. - // 0x07da = 2010 - acknowledge message. - // 0x07ee = 2030 - normal message/request. - unpackLEWord(&buf, &wCommand); - wLen -= 2; - - // Unknown, always 0xe (14) - buf += 2; - wLen -= 2; - - // Sequence number - unpackLEWord(&buf, &wCookie); - wLen -= 2; - - // Unknown, always zeroes - buf += 12; - wLen -= 12; - - // Peer message type - unpackByte(&buf, &bMsgType); - // Peer message flags - unpackByte(&buf, &bMsgFlags); - wLen -= 2; - - // The current status of the user, or whether the message was accepted or not. - // 0x00 - user is online, or message was receipt, or file transfer accepted - // 0x01 - refused - // 0x04 - auto-refused, because of away - // 0x09 - auto-refused, because of occupied - // 0x0a - auto-refused, because of dnd - // 0x0e - auto-refused, because of na - unpackLEWord(&buf, &wStatus); - wLen -= 2; - - // Flags, or priority - // Seen: 1 - Chat request - // 0 - File auto accept (type 3) - // 33 - priority ? - unpackLEWord(&buf, &wFlags); - wLen -= 2; - - // Messagetext. This is either the status message or the actual message - // when this is a PEER_MSG_MSG packet - unpackLEWord(&buf, &wTextLen); - if (wTextLen > 0) { - pszText = (char*)_alloca(wTextLen + 1); - unpackString(&buf, pszText, wTextLen); - pszText[wTextLen] = '\0'; - } - wLen = (wLen - 2) - wTextLen; - - NetLog_Direct("Handling PEER_MSG '%s', command %u, cookie %u, messagetype %u, messageflags %u, status %u, flags %u", pszText, wCommand, wCookie, bMsgType, bMsgFlags, wStatus, wFlags); - - // The remaining actual message is handled either as a status message request, - // a greeting message, a acknowledge or a normal (text, url, file) message - if (wCommand == DIRECT_MESSAGE) { - switch (bMsgType) { - case MTYPE_FILEREQ: // File inits - handleFileRequest(buf, dc->dwRemoteUin, wCookie, 0, 0, pszText, 7, TRUE); - break; - - case MTYPE_AUTOAWAY: - case MTYPE_AUTOBUSY: - case MTYPE_AUTONA: - case MTYPE_AUTODND: - case MTYPE_AUTOFFC: - { - char **szMsg = MirandaStatusToAwayMsg(AwayMsgTypeToStatus(bMsgType)); - if (szMsg) - icq_sendAwayMsgReplyDirect(dc, wCookie, bMsgType, (const char**)szMsg); - } - break; - - case MTYPE_PLUGIN: // Greeting - handleDirectGreetingMessage(dc, buf, wLen, wCommand, wCookie, bMsgType, bMsgFlags, wStatus, wFlags); - break; - - default: - message_ack_params pMsgAck = { 0 }; - uid_str szUID; - - buf -= wTextLen; - wLen += wTextLen; - - pMsgAck.bType = MAT_DIRECT; - pMsgAck.pDC = dc; - pMsgAck.wCookie = wCookie; - pMsgAck.msgType = bMsgType; - pMsgAck.bFlags = bMsgFlags; - handleMessageTypes(dc->dwRemoteUin, szUID, time(0), 0, 0, wCookie, dc->wVersion, (int)bMsgType, (int)bMsgFlags, 0, (DWORD)wLen, wTextLen, (char*)buf, MTF_DIRECT, &pMsgAck); - break; - } - } - else if (wCommand == DIRECT_ACK) { - if (bMsgFlags == 3) { - // this is status reply - uid_str szUID; - - buf -= wTextLen; - wLen += wTextLen; - - handleMessageTypes(dc->dwRemoteUin, szUID, time(0), 0, 0, wCookie, dc->wVersion, (int)bMsgType, (int)bMsgFlags, 2, (DWORD)wLen, wTextLen, (char*)buf, MTF_DIRECT, nullptr); - } - else { - MCONTACT hCookieContact; - cookie_message_data *pCookieData = nullptr; - if (!FindCookie(wCookie, &hCookieContact, (void**)&pCookieData)) - NetLog_Direct("Received an unexpected direct ack"); - else if (hCookieContact != dc->hContact) { - NetLog_Direct("Direct Contact does not match Cookie Contact(0x%x != 0x%x)", dc->hContact, hCookieContact); - ReleaseCookie(wCookie); // This could be a bad idea, but I think it is safe - } - else { // the ack is correct - int ackType = -1; - - switch (bMsgType) { - case MTYPE_PLAIN: - ackType = ACKTYPE_MESSAGE; - break; - case MTYPE_URL: - ackType = ACKTYPE_URL; - break; - case MTYPE_CONTACTS: - ackType = ACKTYPE_CONTACTS; - break; - - case MTYPE_FILEREQ: // File acks - handleFileAck(buf, wLen, dc->dwRemoteUin, wCookie, wStatus); - break; - - case MTYPE_PLUGIN: // Greeting - handleDirectGreetingMessage(dc, buf, wLen, wCommand, wCookie, bMsgType, bMsgFlags, wStatus, wFlags); - break; - - default: - NetLog_Direct("Skipped packet from direct connection"); - break; - } - if (ackType != -1) { // was a good ack to broadcast ? - ProtoBroadcastAck(dc->hContact, ackType, ACKRESULT_SUCCESS, (HANDLE)wCookie, 0); - ReleaseCookie(wCookie); - } - } - } - } - else if (wCommand == DIRECT_CANCEL) - NetLog_Direct("Cannot handle abort messages yet... :("); - else - NetLog_Direct("Unknown wCommand, packet skipped"); -} - -void CIcqProto::handleDirectGreetingMessage(directconnect* dc, PBYTE buf, size_t wLen, WORD wCommand, WORD wCookie, BYTE bMsgType, BYTE bMsgFlags, WORD wStatus, WORD wFlags) -{ - NetLog_Direct("Handling PEER_MSG_GREETING, command %u, cookie %u, messagetype %u, messageflags %u, status %u, flags %u", wCommand, wCookie, bMsgType, bMsgFlags, wStatus, wFlags); - - int typeId; - WORD qt; - if (!unpackPluginTypeId(&buf, &wLen, &typeId, &qt, TRUE)) - return; - - // Length of remaining data - size_t dwLengthToEnd; - unpackLEDWord(&buf, &dwLengthToEnd); - if (dwLengthToEnd < 4 || dwLengthToEnd > wLen) { - NetLog_Direct("Error: Sanity checking failed (%d) in handleDirectGreetingMessage, datalen %u wLen %u", 2, dwLengthToEnd, wLen); - return; - } - - // Length of message/reason - size_t dwDataLength; - unpackLEDWord(&buf, &dwDataLength); - wLen -= 4; - if (dwDataLength > wLen) { - NetLog_Direct("Error: Sanity checking failed (%d) in handleDirectGreetingMessage, datalen %u wLen %u", 3, dwDataLength, wLen); - return; - } - - if (typeId == MTYPE_FILEREQ && wCommand == DIRECT_MESSAGE) { - NetLog_Direct("This is file request"); - char *szMsg = (char*)_alloca(dwDataLength + 1); - unpackString(&buf, szMsg, dwDataLength); - szMsg[dwDataLength] = '\0'; - wLen -= dwDataLength; - - handleFileRequest(buf, dc->dwRemoteUin, wCookie, 0, 0, szMsg, 8, TRUE); - } - else if (typeId == MTYPE_FILEREQ && wCommand == DIRECT_ACK) { - NetLog_Direct("This is file ack"); - char *szMsg = (char*)_alloca(dwDataLength + 1); - unpackString(&buf, szMsg, dwDataLength); - szMsg[dwDataLength] = '\0'; - wLen -= dwDataLength; - - // 50 - file request granted/refused - handleFileAck(buf, wLen, dc->dwRemoteUin, wCookie, wStatus); - } - else if (typeId && wCommand == DIRECT_MESSAGE) { - uid_str szUID; - message_ack_params pMsgAck = { 0 }; - - pMsgAck.bType = MAT_DIRECT; - pMsgAck.pDC = dc; - pMsgAck.wCookie = wCookie; - pMsgAck.msgType = typeId; - handleMessageTypes(dc->dwRemoteUin, szUID, time(0), 0, 0, wCookie, dc->wVersion, typeId, 0, 0, dwLengthToEnd, dwDataLength, (char*)buf, MTF_PLUGIN | MTF_DIRECT, &pMsgAck); - } - else if (typeId == MTYPE_STATUSMSGEXT && wCommand == DIRECT_ACK) { // especially for icq2003b - NetLog_Direct("This is extended status reply"); - - char *szMsg = (char*)_alloca(dwDataLength + 1); - unpackString(&buf, szMsg, dwDataLength); - szMsg[dwDataLength] = '\0'; - - uid_str szUID; - handleMessageTypes(dc->dwRemoteUin, szUID, time(0), 0, 0, wCookie, dc->wVersion, (int)(qt + 0xE7), 3, 2, wLen, dwDataLength, szMsg, MTF_PLUGIN | MTF_DIRECT, nullptr); - } - else if (typeId && wCommand == DIRECT_ACK) { - MCONTACT hCookieContact; - cookie_message_data *pCookieData = nullptr; - - if (!FindCookie(wCookie, &hCookieContact, (void**)&pCookieData)) { - NetLog_Direct("Received an unexpected direct ack"); - } - else if (hCookieContact != dc->hContact) { - NetLog_Direct("Direct Contact does not match Cookie Contact(0x%x != 0x%x)", dc->hContact, hCookieContact); - ReleaseCookie(wCookie); // This could be a bad idea, but I think it is safe - } - else { - int ackType = -1; - - switch (typeId) { - case MTYPE_MESSAGE: - ackType = ACKTYPE_MESSAGE; - break; - case MTYPE_URL: - ackType = ACKTYPE_URL; - break; - case MTYPE_CONTACTS: - ackType = ACKTYPE_CONTACTS; - break; - case MTYPE_SCRIPT_NOTIFY: - { - char *szMsg = (char*)_alloca(dwDataLength + 1); - if (dwDataLength > 0) - memcpy(szMsg, buf, dwDataLength); - szMsg[dwDataLength] = '\0'; - - handleXtrazNotifyResponse(dc->hContact, wCookie, szMsg); - } - break; - - default: - NetLog_Direct("Skipped packet from direct connection"); - break; - } - - if (ackType != -1) { // was a good ack to broadcast ? - ProtoBroadcastAck(dc->hContact, ackType, ACKRESULT_SUCCESS, (HANDLE)wCookie, 0); - } - // Release cookie - ReleaseCookie(wCookie); - } - } - else NetLog_Direct("Unsupported plugin message type %s", typeId); -} diff --git a/protocols/IcqOscarJ/src/icq_fieldnames.cpp b/protocols/IcqOscarJ/src/icq_fieldnames.cpp deleted file mode 100644 index db2ab4bf28..0000000000 --- a/protocols/IcqOscarJ/src/icq_fieldnames.cpp +++ /dev/null @@ -1,576 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2009 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -FieldNamesItem timezonesField[] = -{ - { -100, nullptr } -}; - -const FieldNamesItem countryField[] = { - { 9999, LPGEN("Other") }, - { 93, LPGEN("Afghanistan") }, - { 355, LPGEN("Albania") }, - { 213, LPGEN("Algeria") }, - { 376, LPGEN("Andorra") }, - { 244, LPGEN("Angola") }, - { 1264, LPGEN("Anguilla") }, - { 1268, LPGEN("Antigua and Barbuda") }, - { 54, LPGEN("Argentina") }, - { 374, LPGEN("Armenia") }, - { 297, LPGEN("Aruba") }, - { 247, LPGEN("Ascension Island") }, - { 61, LPGEN("Australia") }, - { 6720, LPGEN("Australia, Antarctic Territory") }, /* added country code 672(0)*/ - { 614, LPGEN("Australia, Christmas Island") }, /* rename (from Christmas Island) and change to official county code 61(4) (from 672) */ - { 61891, LPGEN("Australia, Cocos (Keeling) Islands") }, /* rename and change to official county code 61(891) (from 6102) */ - { 6723, LPGEN("Australia, Norfolk Island") }, /* rename (from Norfolk Island) and change to official county code 672(3) (from 6722) */ - { 43, LPGEN("Austria") }, - { 994, LPGEN("Azerbaijan") }, - { 1242, LPGEN("Bahamas") }, - { 973, LPGEN("Bahrain") }, - { 880, LPGEN("Bangladesh") }, - { 1246, LPGEN("Barbados") }, - //{120, LPGEN("Barbuda")}, /* removed: it is not a country and no special island, see Antigua and Barbuda*/ - { 375, LPGEN("Belarus") }, - { 32, LPGEN("Belgium") }, - { 501, LPGEN("Belize") }, - { 229, LPGEN("Benin") }, - { 1441, LPGEN("Bermuda") }, - { 975, LPGEN("Bhutan") }, - { 591, LPGEN("Bolivia") }, - { 387, LPGEN("Bosnia and Herzegovina") }, - { 267, LPGEN("Botswana") }, - { 55, LPGEN("Brazil") }, - { 106, LPGEN("British Virgin Islands") }, - { 673, LPGEN("Brunei") }, - { 359, LPGEN("Bulgaria") }, - { 226, LPGEN("Burkina Faso") }, - { 257, LPGEN("Burundi") }, - { 855, LPGEN("Cambodia") }, - { 237, LPGEN("Cameroon") }, - { 1002, LPGEN("Canada") }, - { 178, LPGEN("Canary Islands") }, - { 238, LPGEN("Cape Verde") }, - { 1345, LPGEN("Cayman Islands") }, - { 236, LPGEN("Central African Republic") }, - { 235, LPGEN("Chad") }, - { 56, LPGEN("Chile") }, - { 86, LPGEN("China") }, - { 57, LPGEN("Colombia") }, - { 269, LPGEN("Comoros") }, - { 243, LPGEN("Congo, Democratic Republic of the") }, - { 242, LPGEN("Congo, Republic of the") }, - { 682, LPGEN("Cook Islands") }, - { 506, LPGEN("Costa Rica") }, - { 225, LPGEN("Cote d'Ivoire") }, - { 385, LPGEN("Croatia") }, - { 53, LPGEN("Cuba") }, - { 357, LPGEN("Greek, Republic of South Cyprus") }, /* rename coz Turkey, Republic of Northern Cyprus */ - { 420, LPGEN("Czech Republic") }, - { 45, LPGEN("Denmark") }, - { 246, LPGEN("Diego Garcia") }, - { 253, LPGEN("Djibouti") }, - { 1767, LPGEN("Dominica") }, - { 1809, LPGEN("Dominican Republic") }, - { 593, LPGEN("Ecuador") }, - { 20, LPGEN("Egypt") }, - { 503, LPGEN("El Salvador") }, - { 240, LPGEN("Equatorial Guinea") }, - { 291, LPGEN("Eritrea") }, - { 372, LPGEN("Estonia") }, - { 251, LPGEN("Ethiopia") }, - { 3883, LPGEN("Europe") }, /* add county code +388 3 official European Telephony Numbering Space*/ - { 298, LPGEN("Faroe Islands") }, - { 500, LPGEN("Falkland Islands") }, - { 679, LPGEN("Fiji") }, - { 358, LPGEN("Finland") }, - { 33, LPGEN("France") }, - { 5901, LPGEN("French Antilles") }, - { 594, LPGEN("French Guiana") }, - { 689, LPGEN("French Polynesia") }, - { 241, LPGEN("Gabon") }, - { 220, LPGEN("Gambia") }, - { 995, LPGEN("Georgia") }, - { 49, LPGEN("Germany") }, - { 233, LPGEN("Ghana") }, - { 350, LPGEN("Gibraltar") }, - { 30, LPGEN("Greece") }, - { 299, LPGEN("Greenland") }, - { 1473, LPGEN("Grenada") }, - { 590, LPGEN("Guadeloupe") }, - { 1671, LPGEN("Guam, US Territory of") }, - { 502, LPGEN("Guatemala") }, - { 224, LPGEN("Guinea") }, - { 245, LPGEN("Guinea-Bissau") }, - { 592, LPGEN("Guyana") }, - { 509, LPGEN("Haiti") }, - { 504, LPGEN("Honduras") }, - { 852, LPGEN("Hong Kong") }, - { 36, LPGEN("Hungary") }, - { 354, LPGEN("Iceland") }, - { 91, LPGEN("India") }, - { 62, LPGEN("Indonesia") }, - { 98, LPGEN("Iran") }, - { 964, LPGEN("Iraq") }, - { 353, LPGEN("Ireland") }, - { 972, LPGEN("Israel") }, - { 39, LPGEN("Italy") }, - { 1876, LPGEN("Jamaica") }, - { 81, LPGEN("Japan") }, - { 962, LPGEN("Jordan") }, - { 705, LPGEN("Kazakhstan") }, - { 254, LPGEN("Kenya") }, - { 686, LPGEN("Kiribati") }, - { 850, LPGEN("Korea, North") }, - { 82, LPGEN("Korea, South") }, - { 965, LPGEN("Kuwait") }, - { 996, LPGEN("Kyrgyzstan") }, - { 856, LPGEN("Laos") }, - { 371, LPGEN("Latvia") }, - { 961, LPGEN("Lebanon") }, - { 266, LPGEN("Lesotho") }, - { 231, LPGEN("Liberia") }, - { 218, LPGEN("Libya") }, - { 423, LPGEN("Liechtenstein") }, - { 370, LPGEN("Lithuania") }, - { 352, LPGEN("Luxembourg") }, - { 853, LPGEN("Macau") }, - { 389, LPGEN("Macedonia, Republic of") }, - { 261, LPGEN("Madagascar") }, - { 265, LPGEN("Malawi") }, - { 60, LPGEN("Malaysia") }, - { 960, LPGEN("Maldives") }, - { 223, LPGEN("Mali") }, - { 356, LPGEN("Malta") }, - { 692, LPGEN("Marshall Islands") }, - { 596, LPGEN("Martinique") }, - { 222, LPGEN("Mauritania") }, - { 230, LPGEN("Mauritius") }, - { 262, LPGEN("Mayotte") }, - { 52, LPGEN("Mexico") }, - { 691, LPGEN("Micronesia, Federated States of") }, - { 373, LPGEN("Moldova") }, - { 377, LPGEN("Monaco") }, - { 976, LPGEN("Mongolia") }, - { 1664, LPGEN("Montserrat") }, - { 212, LPGEN("Morocco") }, - { 258, LPGEN("Mozambique") }, - { 95, LPGEN("Myanmar") }, - { 264, LPGEN("Namibia") }, - { 674, LPGEN("Nauru") }, - { 977, LPGEN("Nepal") }, - { 31, LPGEN("Netherlands") }, - { 599, LPGEN("Netherlands Antilles") }, /* dissolved 2010 */ - { 5995, LPGEN("St. Maarten") }, /* add new country in 2010 (from Netherlands Antilles) */ - { 5999, LPGEN("Curacao") }, /* add new country in 2010 (from Netherlands Antilles) */ - { 5997, LPGEN("Netherlands (Bonaire Island)") }, /* add new Part of Netherlands in 2010 (from Netherlands Antilles) */ - { 59946, LPGEN("Netherlands (Saba Island)") }, /* add new Part of Netherlands in 2010 (from Netherlands Antilles) */ - { 59938, LPGEN("Netherlands (St. Eustatius Island)") }, /* add new Part of Netherlands in 2010 (from Netherlands Antilles) */ - { 687, LPGEN("New Caledonia") }, - { 64, LPGEN("New Zealand") }, - { 505, LPGEN("Nicaragua") }, - { 227, LPGEN("Niger") }, - { 234, LPGEN("Nigeria") }, - { 683, LPGEN("Niue") }, - { 1670, LPGEN("Northern Mariana Islands, US Territory of") }, /* added NANP */ - { 47, LPGEN("Norway") }, - { 968, LPGEN("Oman") }, - { 92, LPGEN("Pakistan") }, - { 680, LPGEN("Palau") }, - { 507, LPGEN("Panama") }, - { 675, LPGEN("Papua New Guinea") }, - { 595, LPGEN("Paraguay") }, - { 51, LPGEN("Peru") }, - { 63, LPGEN("Philippines") }, - { 48, LPGEN("Poland") }, - { 351, LPGEN("Portugal") }, - { 1939, LPGEN("Puerto Rico") }, - { 974, LPGEN("Qatar") }, - { 262, LPGEN("Reunion") }, - { 40, LPGEN("Romania") }, - { 7, LPGEN("Russia") }, - { 250, LPGEN("Rwanda") }, - { 1684, LPGEN("Samoa (USA)") }, /* rename (from American Samoa) change county code to NANP (from 684) */ - { 685, LPGEN("Samoa, Western") }, /* rename (from Western Samoa) */ - { 290, LPGEN("Saint Helena") }, - { 1869, LPGEN("Saint Kitts and Nevis") }, - { 1758, LPGEN("Saint Lucia") }, - { 508, LPGEN("Saint Pierre and Miquelon") }, - { 1784, LPGEN("Saint Vincent and the Grenadines") }, - { 378, LPGEN("San Marino") }, - { 239, LPGEN("Sao Tome and Principe") }, - { 966, LPGEN("Saudi Arabia") }, - { 442, LPGEN("Scotland") }, - { 221, LPGEN("Senegal") }, - { 248, LPGEN("Seychelles") }, - { 232, LPGEN("Sierra Leone") }, - { 65, LPGEN("Singapore") }, - { 421, LPGEN("Slovakia") }, - { 386, LPGEN("Slovenia") }, - { 677, LPGEN("Solomon Islands") }, - { 252, LPGEN("Somalia") }, - { 27, LPGEN("South Africa") }, - { 34, LPGEN("Spain") }, - { 3492, LPGEN("Spain, Canary Islands") }, /*rename and change county code to 34(92) spain + canary code*/ - { 94, LPGEN("Sri Lanka") }, - { 249, LPGEN("Sudan") }, - { 597, LPGEN("Suriname") }, - { 268, LPGEN("Swaziland") }, - { 46, LPGEN("Sweden") }, - { 41, LPGEN("Switzerland") }, - { 963, LPGEN("Syria") }, - { 886, LPGEN("Taiwan") }, - { 992, LPGEN("Tajikistan") }, - { 255, LPGEN("Tanzania") }, - { 66, LPGEN("Thailand") }, - //{6702, LPGEN("Tinian Island")}, /* removed: it is not a country it is part of Northern Mariana Islands, US Territory of */ - { 670, LPGEN("Timor, East") }, /* added (is part off Northern Mariana Islands but not US Territory*/ - { 228, LPGEN("Togo") }, - { 690, LPGEN("Tokelau") }, - { 676, LPGEN("Tonga") }, - { 1868, LPGEN("Trinidad and Tobago") }, - { 216, LPGEN("Tunisia") }, - { 90, LPGEN("Turkey") }, - { 90392, LPGEN("Turkey, Republic of Northern Cyprus") }, /* added (is diffrent from Greek part)*/ - { 993, LPGEN("Turkmenistan") }, - { 1649, LPGEN("Turks and Caicos Islands") }, - { 688, LPGEN("Tuvalu") }, - { 256, LPGEN("Uganda") }, - { 380, LPGEN("Ukraine") }, - { 971, LPGEN("United Arab Emirates") }, - { 44, LPGEN("United Kingdom") }, - { 598, LPGEN("Uruguay") }, - { 1, LPGEN("USA") }, - { 998, LPGEN("Uzbekistan") }, - { 678, LPGEN("Vanuatu") }, - { 379, LPGEN("Vatican City") }, - { 58, LPGEN("Venezuela") }, - { 84, LPGEN("Vietnam") }, - { 1284, LPGEN("Virgin Islands (UK)") }, /* change county code to NANP (from 105) - rename coz Virgin Islands (USA) */ - { 1340, LPGEN("Virgin Islands (USA)") }, /* change county code to NANP (from 123) */ - { 441, LPGEN("Wales") }, - { 681, LPGEN("Wallis and Futuna") }, - { 967, LPGEN("Yemen") }, - { 38, LPGEN("Yugoslavia") }, - { 381, LPGEN("Serbia") }, /* rename need (from Yugoslavia)*/ - { 383, LPGEN("Kosovo, Republic of") }, /*change country code (from 3811), rename need (from Yugoslavia - Serbia) */ - { 382, LPGEN("Montenegro") }, /* rename need (from Yugoslavia - Montenegro) */ - { 260, LPGEN("Zambia") }, - { 263, LPGEN("Zimbabwe") }, - { 0, nullptr } -}; - -const FieldNamesItem interestsField[] = -{ - { 137, LPGEN("50's") }, - { 134, LPGEN("60's") }, - { 135, LPGEN("70's") }, - { 136, LPGEN("80's") }, - { 100, LPGEN("Art") }, - { 128, LPGEN("Astronomy") }, - { 147, LPGEN("Audio and Visual") }, - { 125, LPGEN("Business") }, - { 146, LPGEN("Business Services") }, - { 101, LPGEN("Cars") }, - { 102, LPGEN("Celebrity Fans") }, - { 130, LPGEN("Clothing") }, - { 103, LPGEN("Collections") }, - { 104, LPGEN("Computers") }, - { 105, LPGEN("Culture") }, - { 122, LPGEN("Ecology") }, - { 139, LPGEN("Entertainment") }, - { 138, LPGEN("Finance and Corporate") }, - { 106, LPGEN("Fitness") }, - { 142, LPGEN("Health and Beauty") }, - { 108, LPGEN("Hobbies") }, - { 150, LPGEN("Home Automation") }, - { 144, LPGEN("Household Products") }, - { 107, LPGEN("Games") }, - { 124, LPGEN("Government") }, - { 109, LPGEN("ICQ - Help") }, - { 110, LPGEN("Internet") }, - { 111, LPGEN("Lifestyle") }, - { 145, LPGEN("Mail Order Catalog") }, - { 143, LPGEN("Media") }, - { 112, LPGEN("Movies and TV") }, - { 113, LPGEN("Music") }, - { 126, LPGEN("Mystics") }, - { 123, LPGEN("News and Media") }, - { 114, LPGEN("Outdoors") }, - { 115, LPGEN("Parenting") }, - { 131, LPGEN("Parties") }, - { 116, LPGEN("Pets and Animals") }, - { 149, LPGEN("Publishing") }, - { 117, LPGEN("Religion") }, - { 141, LPGEN("Retail Stores") }, - { 118, LPGEN("Science") }, - { 119, LPGEN("Skills") }, - { 133, LPGEN("Social science") }, - { 129, LPGEN("Space") }, - { 148, LPGEN("Sporting and Athletic") }, - { 120, LPGEN("Sports") }, - { 127, LPGEN("Travel") }, - { 121, LPGEN("Web Design") }, - { 132, LPGEN("Women") }, - { -1, nullptr } -}; - -const FieldNamesItem languageField[] = -{ - { 55, LPGEN("Afrikaans") }, - { 58, LPGEN("Albanian") }, - { 1, LPGEN("Arabic") }, - { 59, LPGEN("Armenian") }, - { 68, LPGEN("Azerbaijani") }, - { 72, LPGEN("Belorussian") }, - { 2, LPGEN("Bhojpuri") }, - { 56, LPGEN("Bosnian") }, - { 3, LPGEN("Bulgarian") }, - { 4, LPGEN("Burmese") }, - { 5, LPGEN("Cantonese") }, - { 6, LPGEN("Catalan") }, - { 61, LPGEN("Chamorro") }, - { 7, LPGEN("Chinese") }, - { 8, LPGEN("Croatian") }, - { 9, LPGEN("Czech") }, - { 10, LPGEN("Danish") }, - { 11, LPGEN("Dutch") }, - { 12, LPGEN("English") }, - { 13, LPGEN("Esperanto") }, - { 14, LPGEN("Estonian") }, - { 15, LPGEN("Farsi") }, - { 16, LPGEN("Finnish") }, - { 17, LPGEN("French") }, - { 18, LPGEN("Gaelic") }, - { 19, LPGEN("German") }, - { 20, LPGEN("Greek") }, - { 70, LPGEN("Gujarati") }, - { 21, LPGEN("Hebrew") }, - { 22, LPGEN("Hindi") }, - { 23, LPGEN("Hungarian") }, - { 24, LPGEN("Icelandic") }, - { 25, LPGEN("Indonesian") }, - { 26, LPGEN("Italian") }, - { 27, LPGEN("Japanese") }, - { 28, LPGEN("Khmer") }, - { 29, LPGEN("Korean") }, - { 69, LPGEN("Kurdish") }, - { 30, LPGEN("Lao") }, - { 31, LPGEN("Latvian") }, - { 32, LPGEN("Lithuanian") }, - { 65, LPGEN("Macedonian") }, - { 33, LPGEN("Malay") }, - { 63, LPGEN("Mandarin") }, - { 62, LPGEN("Mongolian") }, - { 34, LPGEN("Norwegian") }, - { 57, LPGEN("Persian") }, - { 35, LPGEN("Polish") }, - { 36, LPGEN("Portuguese") }, - { 60, LPGEN("Punjabi") }, - { 37, LPGEN("Romanian") }, - { 38, LPGEN("Russian") }, - { 39, LPGEN("Serbian") }, - { 66, LPGEN("Sindhi") }, - { 40, LPGEN("Slovak") }, - { 41, LPGEN("Slovenian") }, - { 42, LPGEN("Somali") }, - { 43, LPGEN("Spanish") }, - { 44, LPGEN("Swahili") }, - { 45, LPGEN("Swedish") }, - { 46, LPGEN("Tagalog") }, - { 64, LPGEN("Taiwanese") }, - { 71, LPGEN("Tamil") }, - { 47, LPGEN("Tatar") }, - { 48, LPGEN("Thai") }, - { 49, LPGEN("Turkish") }, - { 50, LPGEN("Ukrainian") }, - { 51, LPGEN("Urdu") }, - { 52, LPGEN("Vietnamese") }, - { 67, LPGEN("Welsh") }, - { 53, LPGEN("Yiddish") }, - { 54, LPGEN("Yoruba") }, - { 0, nullptr } -}; - -const FieldNamesItem pastField[] = -{ - { 300, LPGEN("Elementary School") }, - { 301, LPGEN("High School") }, - { 302, LPGEN("College") }, - { 303, LPGEN("University") }, - { 304, LPGEN("Military") }, - { 305, LPGEN("Past Work Place") }, - { 306, LPGEN("Past Organization") }, - { 399, LPGEN("Other") }, - { 0, nullptr } -}; - -const FieldNamesItem genderField[] = -{ - { 'F', LPGEN("Female") }, - { 'M', LPGEN("Male") }, - { 0, nullptr } -}; - -const FieldNamesItem studyLevelField[] = -{ - { 4, LPGEN("Associated degree") }, - { 5, LPGEN("Bachelor's degree") }, - { 1, LPGEN("Elementary") }, - { 2, LPGEN("High-school") }, - { 6, LPGEN("Master's degree") }, - { 7, LPGEN("PhD") }, - { 8, LPGEN("Postdoctoral") }, - { 3, LPGEN("University / College") }, - { 0, nullptr } -}; - -const FieldNamesItem industryField[] = -{ - { 2, LPGEN("Agriculture") }, - { 3, LPGEN("Arts") }, - { 4, LPGEN("Construction") }, - { 5, LPGEN("Consumer Goods") }, - { 6, LPGEN("Corporate Services") }, - { 7, LPGEN("Education") }, - { 8, LPGEN("Finance") }, - { 9, LPGEN("Government") }, - { 10, LPGEN("High Tech") }, - { 11, LPGEN("Legal") }, - { 12, LPGEN("Manufacturing") }, - { 13, LPGEN("Media") }, - { 14, LPGEN("Medical & Health Care") }, - { 15, LPGEN("Non-Profit Organization Management") }, - { 19, LPGEN("Other") }, - { 16, LPGEN("Recreation, Travel & Entertainment") }, - { 17, LPGEN("Service Industry") }, - { 18, LPGEN("Transportation") }, - { 0, nullptr } -}; - -const FieldNamesItem occupationField[] = -{ - { 1, LPGEN("Academic") }, - { 2, LPGEN("Administrative") }, - { 3, LPGEN("Art/Entertainment") }, - { 4, LPGEN("College Student") }, - { 5, LPGEN("Computers") }, - { 6, LPGEN("Community & Social") }, - { 7, LPGEN("Education") }, - { 8, LPGEN("Engineering") }, - { 9, LPGEN("Financial Services") }, - { 10, LPGEN("Government") }, - { 11, LPGEN("High School Student") }, - { 12, LPGEN("Home") }, - { 13, LPGEN("ICQ - Providing Help") }, - { 14, LPGEN("Law") }, - { 15, LPGEN("Managerial") }, - { 16, LPGEN("Manufacturing") }, - { 17, LPGEN("Medical/Health") }, - { 18, LPGEN("Military") }, - { 19, LPGEN("Non-Government Organization") }, - { 20, LPGEN("Professional") }, - { 21, LPGEN("Retail") }, - { 22, LPGEN("Retired") }, - { 23, LPGEN("Science & Research") }, - { 24, LPGEN("Sports") }, - { 25, LPGEN("Technical") }, - { 26, LPGEN("University Student") }, - { 27, LPGEN("Web Building") }, - { 99, LPGEN("Other Services") }, - { 0, nullptr } -}; - -const FieldNamesItem affiliationField[] = -{ - { 200, LPGEN("Alumni Org.") }, - { 201, LPGEN("Charity Org.") }, - { 202, LPGEN("Club/Social Org.") }, - { 203, LPGEN("Community Org.") }, - { 204, LPGEN("Cultural Org.") }, - { 205, LPGEN("Fan Clubs") }, - { 206, LPGEN("Fraternity/Sorority") }, - { 207, LPGEN("Hobbyists Org.") }, - { 208, LPGEN("International Org.") }, - { 209, LPGEN("Nature and Environment Org.") }, - { 210, LPGEN("Professional Org.") }, - { 211, LPGEN("Scientific/Technical Org.") }, - { 212, LPGEN("Self Improvement Group") }, - { 213, LPGEN("Spiritual/Religious Org.") }, - { 214, LPGEN("Sports Org.") }, - { 215, LPGEN("Support Org.") }, - { 216, LPGEN("Trade and Business Org.") }, - { 217, LPGEN("Union") }, - { 218, LPGEN("Volunteer Org.") }, - { 299, LPGEN("Other") }, - { 0, nullptr } -}; - -const FieldNamesItem agesField[] = -{ - { 0x0011000D, LPGEN("13-17") }, - { 0x00160012, LPGEN("18-22") }, - { 0x001D0017, LPGEN("23-29") }, - { 0x0027001E, LPGEN("30-39") }, - { 0x00310028, LPGEN("40-49") }, - { 0x003B0032, LPGEN("50-59") }, - { 0x2710003C, LPGEN("60-above") }, - { -1, nullptr } -}; - -const FieldNamesItem maritalField[] = -{ - { 10, LPGEN("Single") }, - { 11, LPGEN("Close relationships") }, - { 12, LPGEN("Engaged") }, - { 20, LPGEN("Married") }, - { 30, LPGEN("Divorced") }, - { 31, LPGEN("Separated") }, - { 40, LPGEN("Widowed") }, - { 50, LPGEN("Open relationship") }, - { 255, LPGEN("Other") }, - { 0, nullptr } -}; - -char* LookupFieldName(const FieldNamesItem *table, int code) -{ - if (code != 0) - for (int i = 0; table[i].text; i++) - if (table[i].code == code) - return table[i].text; - - return nullptr; -} - -char* LookupFieldNameUtf(const FieldNamesItem *table, int code, char *str, size_t strsize) -{ - char *szText = LookupFieldName(table, code); - if (szText) - return ICQTranslateUtfStatic(szText, str, strsize); - - return nullptr; -} diff --git a/protocols/IcqOscarJ/src/icq_fieldnames.h b/protocols/IcqOscarJ/src/icq_fieldnames.h deleted file mode 100644 index e7b2fa009b..0000000000 --- a/protocols/IcqOscarJ/src/icq_fieldnames.h +++ /dev/null @@ -1,48 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2009 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// ----------------------------------------------------------------------------- - -#pragma once - -struct FieldNamesItem -{ - int code; - char *text; -}; - -extern FieldNamesItem timezonesField[]; -extern const FieldNamesItem countryField[]; -extern const FieldNamesItem interestsField[]; -extern const FieldNamesItem languageField[]; -extern const FieldNamesItem pastField[]; -extern const FieldNamesItem genderField[]; -extern const FieldNamesItem agesField[]; -extern const FieldNamesItem studyLevelField[]; -extern const FieldNamesItem industryField[]; -extern const FieldNamesItem occupationField[]; -extern const FieldNamesItem affiliationField[]; -extern const FieldNamesItem maritalField[]; - -char *LookupFieldName(const FieldNamesItem *table, int code); -char *LookupFieldNameUtf(const FieldNamesItem *table, int code, char *str, size_t strsize); diff --git a/protocols/IcqOscarJ/src/icq_filerequests.cpp b/protocols/IcqOscarJ/src/icq_filerequests.cpp deleted file mode 100644 index 793caa9712..0000000000 --- a/protocols/IcqOscarJ/src/icq_filerequests.cpp +++ /dev/null @@ -1,191 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2009 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -void CIcqProto::handleFileAck(PBYTE buf, size_t wLen, DWORD dwUin, DWORD dwCookie, WORD wStatus) -{ - char* pszFileName = nullptr; - DWORD dwFileSize; - MCONTACT hCookieContact; - WORD wPort; - filetransfer* ft; - - // Find the filetransfer that belongs to this response - if (!FindCookie(dwCookie, &hCookieContact, (void**)&ft)) { - NetLog_Direct("Error: Received unexpected file transfer request response"); - return; - } - - FreeCookie(dwCookie); - - if (hCookieContact != HContactFromUIN(dwUin, nullptr)) { - NetLog_Direct("Error: UINs do not match in file transfer request response"); - return; - } - - // If status != 0, a request has been denied - if (wStatus != 0) { - NetLog_Direct("File transfer denied by %u.", dwUin); - ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_DENIED, (HANDLE)ft, 0); - - FreeCookie(dwCookie); - - return; - } - - if (wLen < 6) { // sanity check - NetLog_Direct("Ignoring malformed file transfer request response"); - return; - } - - // Port to connect to - unpackWord(&buf, &wPort); - ft->dwRemotePort = wPort; - wLen -= 2; - - // Unknown - buf += 2; - wLen -= 2; - - // Filename - size_t wFilenameLength; - unpackLEWord(&buf, &wFilenameLength); - if (wFilenameLength > 0) { - if (wFilenameLength > wLen - 2) - wFilenameLength = wLen - 2; - pszFileName = (char*)_alloca(wFilenameLength + 1); - unpackString(&buf, pszFileName, wFilenameLength); - pszFileName[wFilenameLength] = '\0'; - } - wLen -= wFilenameLength + 2; - - if (wLen >= 4) - unpackLEDWord(&buf, &dwFileSize); - else - dwFileSize = 0; - - NetLog_Direct("File transfer ack from %u, port %u, name %s, size %u", dwUin, ft->dwRemotePort, pszFileName, dwFileSize); - - ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTING, (HANDLE)ft, 0); - - OpenDirectConnection(ft->hContact, DIRECTCONN_FILE, ft); -} - -filetransfer* CIcqProto::CreateFileTransfer(MCONTACT hContact, DWORD dwUin, int nVersion) -{ - filetransfer *ft = CreateIcqFileTransfer(); - - ft->dwUin = dwUin; - ft->hContact = hContact; - ft->nVersion = nVersion; - ft->pMessage.bMessageType = MTYPE_FILEREQ; - InitMessageCookie(&ft->pMessage); - - return ft; -} - -// pszDescription points to a string with the reason -// buf points to the first data after the string -void CIcqProto::handleFileRequest(PBYTE buf, DWORD dwUin, DWORD dwCookie, DWORD dwID1, DWORD dwID2, char* pszDescription, int nVersion, BOOL bDC) -{ - BOOL bEmptyDesc = FALSE; - if (mir_strlen(pszDescription) == 0) { - pszDescription = Translate("No description given"); - bEmptyDesc = TRUE; - } - - // Empty port+pad - buf += 4; - - // Filename - size_t wFilenameLength; - unpackLEWord(&buf, &wFilenameLength); - if (!wFilenameLength) { - NetLog_Direct("Ignoring malformed file send request"); - return; - } - - char *pszFileName = (char*)_alloca(wFilenameLength + 1); - unpackString(&buf, pszFileName, wFilenameLength); - pszFileName[wFilenameLength] = '\0'; - - // Total filesize - DWORD dwFileSize; - unpackLEDWord(&buf, &dwFileSize); - - int bAdded; - MCONTACT hContact = HContactFromUIN(dwUin, &bAdded); - - // Initialize a filetransfer struct - filetransfer *ft = CreateFileTransfer(hContact, dwUin, nVersion); - ft->dwCookie = dwCookie; - ft->szFilename = mir_strdup(pszFileName); - ft->szDescription = nullptr; - ft->fileId = -1; - ft->dwTotalSize = dwFileSize; - ft->pMessage.dwMsgID1 = dwID1; - ft->pMessage.dwMsgID2 = dwID2; - ft->bDC = bDC; - ft->bEmptyDesc = bEmptyDesc; - - // Send chain event - wchar_t* ptszFileName = mir_utf8decodeW(pszFileName); - - PROTORECVFILE pre = { 0 }; - pre.dwFlags = PRFF_UNICODE; - pre.fileCount = 1; - pre.timestamp = time(0); - pre.descr.w = mir_utf8decodeW(pszDescription); - pre.files.w = &ptszFileName; - pre.lParam = (LPARAM)ft; - ProtoChainRecvFile(hContact, &pre); - - mir_free(pre.descr.w); - mir_free(ptszFileName); -} - -void CIcqProto::handleDirectCancel() -{ - NetLog_Direct("handleDirectCancel: Unhandled cancel"); -} - -// ******************************************************************************* - -void CIcqProto::icq_CancelFileTransfer(filetransfer* ft) -{ - DWORD dwCookie; - if (FindCookieByData(ft, &dwCookie, nullptr)) - FreeCookie(dwCookie); /* this bit stops a send that's waiting for acceptance */ - - if (IsValidFileTransfer(ft)) { // Transfer still out there, end it - NetLib_CloseConnection(&ft->hConnection, FALSE); - - ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0); - - if (!FindFileTransferDC(ft)) // Release orphan structure only - SafeReleaseFileTransfer((basic_filetransfer**)&ft); - } -} diff --git a/protocols/IcqOscarJ/src/icq_filetransfer.cpp b/protocols/IcqOscarJ/src/icq_filetransfer.cpp deleted file mode 100644 index 9caec02d08..0000000000 --- a/protocols/IcqOscarJ/src/icq_filetransfer.cpp +++ /dev/null @@ -1,482 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2009 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -static void file_buildProtoFileTransferStatus(filetransfer* ft, PROTOFILETRANSFERSTATUS* pfts) -{ - memset(pfts, 0, sizeof(PROTOFILETRANSFERSTATUS)); - pfts->hContact = ft->hContact; - pfts->flags = PFTS_UTF | (ft->sending ? PFTS_SENDING : PFTS_RECEIVING); /* Standard FT is Ansi only */ - if (ft->sending) - pfts->pszFiles.a = ft->pszFiles; - else - pfts->pszFiles.a = nullptr; /* FIXME */ - pfts->totalFiles = ft->dwFileCount; - pfts->currentFileNumber = ft->iCurrentFile; - pfts->totalBytes = ft->dwTotalSize; - pfts->totalProgress = ft->dwBytesDone; - pfts->szWorkingDir.a = ft->szSavePath; - pfts->szCurrentFile.a = ft->szThisFile; - pfts->currentFileSize = ft->dwThisFileSize; - pfts->currentFileTime = ft->dwThisFileDate; - pfts->currentFileProgress = ft->dwFileBytesDone; -} - - -static void file_sendTransferSpeed(CIcqProto* ppro, directconnect* dc) -{ - icq_packet packet; - directPacketInit(&packet, 5); - packByte(&packet, PEER_FILE_SPEED); /* Ident */ - packLEDWord(&packet, dc->ft->dwTransferSpeed); - ppro->sendDirectPacket(dc, &packet); -} - - -static void file_sendNick(CIcqProto* ppro, directconnect* dc) -{ - ptrA tmp(ppro->getStringA("Nick")); - char *szNick = NEWSTR_ALLOCA((tmp == NULL) ? "" : tmp); - size_t nNickLen = mir_strlen(szNick); - - icq_packet packet; - directPacketInit(&packet, 8 + nNickLen); - packByte(&packet, PEER_FILE_INIT_ACK); /* Ident */ - packLEDWord(&packet, dc->ft->dwTransferSpeed); - packLEWord(&packet, WORD(nNickLen + 1)); - packBuffer(&packet, (LPBYTE)szNick, nNickLen + 1); - ppro->sendDirectPacket(dc, &packet); -} - - -static void file_sendNextFile(CIcqProto* ppro, directconnect* dc) -{ - struct _stati64 statbuf; - char szThisSubDir[MAX_PATH]; - - if (dc->ft->iCurrentFile >= (int)dc->ft->dwFileCount) { - ppro->ProtoBroadcastAck(dc->ft->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, dc->ft, 0); - ppro->CloseDirectConnection(dc); - dc->ft->hConnection = nullptr; - return; - } - - dc->ft->szThisFile = dc->ft->pszFiles[dc->ft->iCurrentFile]; - if (FileStatUtf(dc->ft->szThisFile, &statbuf)) { - ppro->icq_LogMessage(LOG_ERROR, LPGEN("Your file transfer has been aborted because one of the files that you selected to send is no longer readable from the disk. You may have deleted or moved it.")); - ppro->CloseDirectConnection(dc); - dc->ft->hConnection = nullptr; - return; - } - - char *pszThisFileName = FindFilePathContainer((LPCSTR*)dc->ft->pszFiles, dc->ft->iCurrentFile, szThisSubDir); - - if (statbuf.st_mode & _S_IFDIR) - dc->ft->currentIsDir = 1; - else { - dc->ft->currentIsDir = 0; - dc->ft->fileId = OpenFileUtf(dc->ft->szThisFile, _O_BINARY | _O_RDONLY, _S_IREAD); - if (dc->ft->fileId == -1) { - ppro->icq_LogMessage(LOG_ERROR, LPGEN("Your file transfer has been aborted because one of the files that you selected to send is no longer readable from the disk. You may have deleted or moved it.")); - ppro->CloseDirectConnection(dc); - dc->ft->hConnection = nullptr; - return; - } - } - - dc->ft->dwThisFileSize = statbuf.st_size; - dc->ft->dwThisFileDate = statbuf.st_mtime; - dc->ft->dwFileBytesDone = 0; - - char *szThisFileNameAnsi = nullptr, *szThisSubDirAnsi = nullptr; - if (!utf8_decode(pszThisFileName, &szThisFileNameAnsi)) - szThisFileNameAnsi = _strdup(pszThisFileName); // Legacy fix - if (!utf8_decode(szThisSubDir, &szThisSubDirAnsi)) - szThisSubDirAnsi = _strdup(szThisSubDir); // Legacy fix - - size_t wThisFileNameLen = mir_strlen(szThisFileNameAnsi); - size_t wThisSubDirLen = mir_strlen(szThisSubDirAnsi); - - icq_packet packet; - directPacketInit(&packet, 20 + wThisFileNameLen + wThisSubDirLen); - packByte(&packet, PEER_FILE_NEXTFILE); /* Ident */ - packByte(&packet, (BYTE)((statbuf.st_mode & _S_IFDIR) != 0)); // Is subdir - packLEWord(&packet, WORD(wThisFileNameLen + 1)); - packBuffer(&packet, (LPBYTE)szThisFileNameAnsi, wThisFileNameLen + 1); - packLEWord(&packet, WORD(wThisSubDirLen + 1)); - packBuffer(&packet, (LPBYTE)szThisSubDirAnsi, wThisSubDirLen + 1); - packLEDWord(&packet, dc->ft->dwThisFileSize); - packLEDWord(&packet, statbuf.st_mtime); - packLEDWord(&packet, dc->ft->dwTransferSpeed); - SAFE_FREE(&szThisFileNameAnsi); - SAFE_FREE(&szThisSubDirAnsi); - ppro->sendDirectPacket(dc, &packet); - - ppro->ProtoBroadcastAck(dc->ft->hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, dc->ft, 0); -} - - -static void file_sendResume(CIcqProto* ppro, directconnect* dc) -{ - icq_packet packet; - directPacketInit(&packet, 17); - packByte(&packet, PEER_FILE_RESUME); /* Ident */ - packLEDWord(&packet, dc->ft->dwFileBytesDone); /* file resume */ - packLEDWord(&packet, 0); /* unknown */ - packLEDWord(&packet, dc->ft->dwTransferSpeed); - packLEDWord(&packet, dc->ft->iCurrentFile + 1); /* file number */ - ppro->sendDirectPacket(dc, &packet); -} - - -static void file_sendData(CIcqProto* ppro, directconnect* dc) -{ - BYTE buf[2048]; - int bytesRead = 0; - - if (!dc->ft->currentIsDir) { - icq_packet packet; - - if (dc->ft->fileId == -1) - return; - bytesRead = _read(dc->ft->fileId, buf, sizeof(buf)); - if (bytesRead == -1) - return; - - directPacketInit(&packet, 1 + bytesRead); - packByte(&packet, PEER_FILE_DATA); /* Ident */ - packBuffer(&packet, buf, bytesRead); - ppro->sendDirectPacket(dc, &packet); - } - - dc->ft->dwBytesDone += bytesRead; - dc->ft->dwFileBytesDone += bytesRead; - - if (GetTickCount() > dc->ft->dwLastNotify + 500 || bytesRead == 0) { - PROTOFILETRANSFERSTATUS pfts; - - file_buildProtoFileTransferStatus(dc->ft, &pfts); - ppro->ProtoBroadcastAck(dc->ft->hContact, ACKTYPE_FILE, ACKRESULT_DATA, dc->ft, (LPARAM)&pfts); - - dc->ft->dwLastNotify = GetTickCount(); - } - - if (bytesRead == 0) { - if (!dc->ft->currentIsDir) _close(dc->ft->fileId); - dc->ft->fileId = -1; - dc->wantIdleTime = 0; - dc->ft->iCurrentFile++; - file_sendNextFile(ppro, dc); /* this will close the socket if no more files */ - } -} - - -void CIcqProto::handleFileTransferIdle(directconnect* dc) -{ - file_sendData(this, dc); -} - - -void CIcqProto::icq_sendFileResume(filetransfer *ft, int action, const char *szFilename) -{ - if (ft->hConnection == nullptr) - return; - - directconnect *dc = FindFileTransferDC(ft); - if (!dc) - return; // something is broken... - - int openFlags; - - switch (action) { - case FILERESUME_RESUME: - openFlags = _O_BINARY | _O_WRONLY; - break; - - case FILERESUME_OVERWRITE: - openFlags = _O_BINARY | _O_CREAT | _O_TRUNC | _O_WRONLY; - ft->dwFileBytesDone = 0; - break; - - case FILERESUME_SKIP: - openFlags = _O_BINARY | _O_WRONLY; - ft->dwFileBytesDone = ft->dwThisFileSize; - break; - - case FILERESUME_RENAME: - openFlags = _O_BINARY | _O_CREAT | _O_TRUNC | _O_WRONLY; - SAFE_FREE(&ft->szThisFile); - ft->szThisFile = null_strdup(szFilename); - ft->dwFileBytesDone = 0; - break; - - default: - openFlags = 0; - } - - ft->fileId = OpenFileUtf(ft->szThisFile, openFlags, _S_IREAD | _S_IWRITE); - if (ft->fileId == -1) { - icq_LogMessage(LOG_ERROR, LPGEN("Your file receive has been aborted because Miranda could not open the destination file in order to write to it. You may be trying to save to a read-only folder.")); - NetLib_CloseConnection(&ft->hConnection, FALSE); - return; - } - - if (action == FILERESUME_RESUME) - ft->dwFileBytesDone = _lseek(ft->fileId, 0, SEEK_END); - else - _lseek(ft->fileId, ft->dwFileBytesDone, SEEK_SET); - - ft->dwBytesDone += ft->dwFileBytesDone; - - file_sendResume(this, dc); - - ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ft, 0); -} - - -// small utility function -void NormalizeBackslash(char* path) -{ - size_t len = mir_strlen(path); - if (len && path[len - 1] != '\\') - mir_strcat(path, "\\"); -} - -/* a file transfer looks like this: -S: 0 -R: 5 -R: 1 -S: 2 -R: 3 -S: 6 * many -(for more files, send 2, 3, 6*many) -*/ - -void CIcqProto::handleFileTransferPacket(directconnect* dc, PBYTE buf, size_t wLen) -{ - if (wLen < 1) - return; - - NetLog_Direct("Handling file packet"); - - switch (buf[0]) { - case PEER_FILE_INIT: /* first packet of a file transfer */ - if (dc->initialised) - return; - if (wLen < 19) - return; - buf += 5; /* id, and unknown 0 */ - dc->type = DIRECTCONN_FILE; - { - DWORD dwFileCount; - DWORD dwTotalSize; - DWORD dwTransferSpeed; - size_t wNickLength; - int bAdded; - - unpackLEDWord(&buf, &dwFileCount); - unpackLEDWord(&buf, &dwTotalSize); - unpackLEDWord(&buf, &dwTransferSpeed); - unpackLEWord(&buf, &wNickLength); - - dc->ft = FindExpectedFileRecv(dc->dwRemoteUin, dwTotalSize); - if (dc->ft == nullptr) { - NetLog_Direct("Unexpected file receive"); - CloseDirectConnection(dc); - return; - } - dc->ft->dwFileCount = dwFileCount; - dc->ft->dwTransferSpeed = dwTransferSpeed; - dc->ft->hContact = HContactFromUIN(dc->ft->dwUin, &bAdded); - dc->ft->dwBytesDone = 0; - dc->ft->iCurrentFile = -1; - dc->ft->fileId = -1; - dc->ft->hConnection = dc->hConnection; - dc->ft->dwLastNotify = GetTickCount(); - - dc->initialised = 1; - - file_sendTransferSpeed(this, dc); - file_sendNick(this, dc); - } - ProtoBroadcastAck(dc->ft->hContact, ACKTYPE_FILE, ACKRESULT_INITIALISING, dc->ft, 0); - break; - - case PEER_FILE_INIT_ACK: - if (wLen < 8) - return; - buf++; - unpackLEDWord(&buf, &dc->ft->dwTransferSpeed); - /* followed by nick */ - file_sendNextFile(this, dc); - break; - - case PEER_FILE_NEXTFILE: - if (wLen < 20) - return; - buf++; /* id */ - { - size_t wThisFilenameLen, wSubdirLen; - BYTE isDirectory; - unpackByte(&buf, &isDirectory); - unpackLEWord(&buf, &wThisFilenameLen); - if (wLen < 19 + wThisFilenameLen) - return; - - SAFE_FREE(&dc->ft->szThisFile); - char *szAnsi = (char *)_alloca(wThisFilenameLen + 1); - memcpy(szAnsi, buf, wThisFilenameLen); - szAnsi[wThisFilenameLen] = '\0'; - dc->ft->szThisFile = ansi_to_utf8(szAnsi); - buf += wThisFilenameLen; - - unpackLEWord(&buf, &wSubdirLen); - if (wLen < 18 + wThisFilenameLen + wSubdirLen) - return; - SAFE_FREE(&dc->ft->szThisSubdir); - szAnsi = (char *)_alloca(wSubdirLen + 1); - memcpy(szAnsi, buf, wSubdirLen); - szAnsi[wSubdirLen] = '\0'; - dc->ft->szThisSubdir = ansi_to_utf8(szAnsi); - buf += wSubdirLen; - - unpackLEDWord(&buf, &dc->ft->dwThisFileSize); - unpackLEDWord(&buf, &dc->ft->dwThisFileDate); - unpackLEDWord(&buf, &dc->ft->dwTransferSpeed); - - /* no cheating with paths */ - if (!IsValidRelativePath(dc->ft->szThisFile) || !IsValidRelativePath(dc->ft->szThisSubdir)) { - NetLog_Direct("Invalid path information"); - break; - } - - char *szFullPath = (char*)SAFE_MALLOC(mir_strlen(dc->ft->szSavePath) + mir_strlen(dc->ft->szThisSubdir) + mir_strlen(dc->ft->szThisFile) + 3); - mir_strcpy(szFullPath, dc->ft->szSavePath); - NormalizeBackslash(szFullPath); - mir_strcat(szFullPath, dc->ft->szThisSubdir); - NormalizeBackslash(szFullPath); - // _chdir(szFullPath); // set current dir - not very useful - mir_strcat(szFullPath, dc->ft->szThisFile); - // we joined the full path to dest file - SAFE_FREE(&dc->ft->szThisFile); - dc->ft->szThisFile = szFullPath; - - dc->ft->dwFileBytesDone = 0; - dc->ft->iCurrentFile++; - - if (isDirectory) { - MakeDirUtf(dc->ft->szThisFile); - dc->ft->fileId = -1; - } - else { - /* file resume */ - PROTOFILETRANSFERSTATUS pfts = {}; - - file_buildProtoFileTransferStatus(dc->ft, &pfts); - if (ProtoBroadcastAck(dc->ft->hContact, ACKTYPE_FILE, ACKRESULT_FILERESUME, dc->ft, (LPARAM)&pfts)) - break; /* UI supports resume: it will call PS_FILERESUME */ - - dc->ft->fileId = OpenFileUtf(dc->ft->szThisFile, _O_BINARY | _O_CREAT | _O_TRUNC | _O_WRONLY, _S_IREAD | _S_IWRITE); - if (dc->ft->fileId == -1) { - icq_LogMessage(LOG_ERROR, LPGEN("Your file receive has been aborted because Miranda could not open the destination file in order to write to it. You may be trying to save to a read-only folder.")); - CloseDirectConnection(dc); - dc->ft->hConnection = nullptr; - break; - } - } - } - file_sendResume(this, dc); - ProtoBroadcastAck(dc->ft->hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, dc->ft, 0); - break; - - case PEER_FILE_RESUME: - if (dc->ft->fileId == -1 && !dc->ft->currentIsDir) - return; - if (wLen < 13) - return; - if (wLen < 17) - NetLog_Direct("Warning: Received short PEER_FILE_RESUME"); - buf++; - { - DWORD dwRestartFrom; - - unpackLEDWord(&buf, &dwRestartFrom); - if (dwRestartFrom > dc->ft->dwThisFileSize) - return; - buf += 4; /* unknown. 0 */ - unpackLEDWord(&buf, &dc->ft->dwTransferSpeed); - buf += 4; /* unknown. 1 */ - if (!dc->ft->currentIsDir) - _lseek(dc->ft->fileId, dwRestartFrom, 0); - dc->wantIdleTime = 1; - dc->ft->dwBytesDone += dwRestartFrom; - dc->ft->dwFileBytesDone += dwRestartFrom; - } - break; - - case PEER_FILE_SPEED: - if (wLen < 5) - return; - buf++; - unpackLEDWord(&buf, &dc->ft->dwTransferSpeed); - dc->ft->dwLastNotify = GetTickCount(); - break; - - case PEER_FILE_DATA: - if (!dc->ft->currentIsDir) { - if (dc->ft->fileId == -1) - break; - buf++; wLen--; - _write(dc->ft->fileId, buf, (unsigned)wLen); - } - else - wLen = 0; - dc->ft->dwBytesDone += (DWORD)wLen; - dc->ft->dwFileBytesDone += (DWORD)wLen; - if (GetTickCount() > dc->ft->dwLastNotify + 500 || wLen < 2048) { - PROTOFILETRANSFERSTATUS pfts; - - file_buildProtoFileTransferStatus(dc->ft, &pfts); - ProtoBroadcastAck(dc->ft->hContact, ACKTYPE_FILE, ACKRESULT_DATA, dc->ft, (LPARAM)&pfts); - dc->ft->dwLastNotify = GetTickCount(); - } - if (wLen < 2048) { - /* EOF */ - if (!dc->ft->currentIsDir) - _close(dc->ft->fileId); - dc->ft->fileId = -1; - if ((DWORD)dc->ft->iCurrentFile == dc->ft->dwFileCount - 1) { - dc->type = DIRECTCONN_CLOSING; /* this guarantees that we won't accept any more data but that the sender is still free to closesocket() neatly */ - ProtoBroadcastAck(dc->ft->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, dc->ft, 0); - } - } - break; - - default: - NetLog_Direct("Unknown file transfer packet ignored."); - break; - } -} diff --git a/protocols/IcqOscarJ/src/icq_firstrun.cpp b/protocols/IcqOscarJ/src/icq_firstrun.cpp deleted file mode 100644 index 051d2a8974..0000000000 --- a/protocols/IcqOscarJ/src/icq_firstrun.cpp +++ /dev/null @@ -1,108 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2009 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -static void accountLoadDetails(CIcqProto *ppro, HWND hwndDlg) -{ - char pszUIN[20]; - DWORD dwUIN = ppro->getContactUin(NULL); - if (dwUIN) { - mir_snprintf(pszUIN, "%u", dwUIN); - SetDlgItemTextA(hwndDlg, IDC_UIN, pszUIN); - } - - char pszPwd[PASSWORDMAXLEN + 1]; - if (ppro->GetUserStoredPassword(pszPwd)) - SetDlgItemTextA(hwndDlg, IDC_PW, pszPwd); -} - -INT_PTR CALLBACK icq_FirstRunDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - CIcqProto* ppro = (CIcqProto*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - - switch (msg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - - ppro = (CIcqProto*)lParam; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam); - - Window_SetIcon_IcoLib(hwndDlg, ppro->m_hProtoIcon); - - SendDlgItemMessage(hwndDlg, IDC_PW, EM_LIMITTEXT, PASSWORDMAXLEN, 0); - - accountLoadDetails(ppro, hwndDlg); - return TRUE; - - case WM_DESTROY: - Window_FreeIcon_IcoLib(hwndDlg); - break; - - case WM_CLOSE: - EndDialog(hwndDlg, 0); - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_REGISTER: - Utils_OpenUrl(URL_REGISTER); - break; - - case IDC_UIN: - case IDC_PW: - if (HIWORD(wParam) == EN_CHANGE && (HWND)lParam == GetFocus()) { - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - break; - } - } - break; - - case WM_NOTIFY: - switch (((LPNMHDR)lParam)->code) { - case PSN_APPLY: - char str[128]; - GetDlgItemTextA(hwndDlg, IDC_UIN, str, _countof(str)); - ppro->setDword(UNIQUEIDSETTING, atoi(str)); - - GetDlgItemTextA(hwndDlg, IDC_PW, str, _countof(ppro->m_szPassword)); - mir_strcpy(ppro->m_szPassword, str); - ppro->setString("Password", str); - break; - - case PSN_RESET: - accountLoadDetails(ppro, hwndDlg); - break; - } - break; - } - - return FALSE; -} - -INT_PTR CIcqProto::OnCreateAccMgrUI(WPARAM, LPARAM lParam) -{ - return (INT_PTR)CreateDialogParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_ICQACCOUNT), (HWND)lParam, icq_FirstRunDlgProc, LPARAM(this)); -} diff --git a/protocols/IcqOscarJ/src/icq_http.cpp b/protocols/IcqOscarJ/src/icq_http.cpp deleted file mode 100644 index da6777799e..0000000000 --- a/protocols/IcqOscarJ/src/icq_http.cpp +++ /dev/null @@ -1,198 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000,2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001,2002 Jon Keating, Richard Hughes -// Copyright © 2002,2003,2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004,2005,2006 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// HTTP Gateway Handling routines -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -int icq_httpGatewayInit(HNETLIBCONN hConn, NETLIBOPENCONNECTION*, NETLIBHTTPREQUEST *nlhr) -{ - // initial response from ICQ http gateway - size_t wLen, wVersion, wType; - WORD wIpLen; - DWORD dwSid1, dwSid2, dwSid3, dwSid4; - BYTE *buf; - char szSid[33], szHttpServer[256], szHttpGetUrl[300], szHttpPostUrl[300]; - - if (nlhr->dataLength < 31) { - SetLastError(ERROR_INVALID_DATA); - return 0; - } - - buf = (PBYTE)nlhr->pData; - unpackWord(&buf, &wLen); - unpackWord(&buf, &wVersion); /* always 0x0443 */ - unpackWord(&buf, &wType); /* hello reply */ - buf += 6; /* dunno */ - unpackDWord(&buf, &dwSid1); - unpackDWord(&buf, &dwSid2); - unpackDWord(&buf, &dwSid3); - unpackDWord(&buf, &dwSid4); - mir_snprintf(szSid, "%08x%08x%08x%08x", dwSid1, dwSid2, dwSid3, dwSid4); - unpackWord(&buf, &wIpLen); - - if (nlhr->dataLength < 30 + wIpLen || wIpLen == 0 || wIpLen > sizeof(szHttpServer) - 1) { - SetLastError(ERROR_INVALID_DATA); - return 0; - } - - SetGatewayIndex(hConn, 1); // new master connection begins here - - memcpy(szHttpServer, buf, wIpLen); - szHttpServer[wIpLen] = '\0'; - - NETLIBHTTPPROXYINFO nlhpi = {}; - nlhpi.flags = NLHPIF_USEPOSTSEQUENCE; - nlhpi.szHttpGetUrl = szHttpGetUrl; - nlhpi.szHttpPostUrl = szHttpPostUrl; - nlhpi.firstPostSequence = 1; - mir_snprintf(szHttpGetUrl, "http://%s/monitor?sid=%s", szHttpServer, szSid); - mir_snprintf(szHttpPostUrl, "http://%s/data?sid=%s&seq=", szHttpServer, szSid); - return Netlib_SetHttpProxyInfo(hConn, &nlhpi); -} - - - -int icq_httpGatewayBegin(HNETLIBCONN hConn, NETLIBOPENCONNECTION* nloc) -{ // open our "virual data connection" - icq_packet packet; - size_t serverNameLen; - - serverNameLen = mir_strlen(nloc->szHost); - - packet.wLen = (WORD)(serverNameLen + 4); - write_httphdr(&packet, HTTP_PACKETTYPE_LOGIN, GetGatewayIndex(hConn)); - packWord(&packet, (WORD)serverNameLen); - packBuffer(&packet, (LPBYTE)nloc->szHost, serverNameLen); - packWord(&packet, nloc->wPort); - INT_PTR res = Netlib_Send(hConn, (char*)packet.pData, packet.wLen, MSG_DUMPPROXY | MSG_NOHTTPGATEWAYWRAP); - SAFE_FREE((void**)&packet.pData); - - return res != SOCKET_ERROR; -} - - - -int icq_httpGatewayWrapSend(HNETLIBCONN hConn, PBYTE buf, int len, int flags) -{ - PBYTE sendBuf = buf; - int sendLen = len; - int sendResult = 0; - - while (sendLen > 0) { // imitate polite behaviour of icq5.1 and split large packets - icq_packet packet; - WORD curLen; - int curResult; - - if (sendLen > 512) curLen = 512; else curLen = (WORD)sendLen; - // send wrapped data - packet.wLen = curLen; - write_httphdr(&packet, HTTP_PACKETTYPE_FLAP, GetGatewayIndex(hConn)); - packBuffer(&packet, sendBuf, curLen); - - curResult = Netlib_Send(hConn, (char*)packet.pData, packet.wLen, flags); - - SAFE_FREE((void**)&packet.pData); - - // sending failed, end loop - if (curResult <= 0) - return curResult; - // calculare real number of data bytes sent - if (curResult > 14) sendResult += curResult - 14; - // move on - sendLen -= curLen; - sendBuf += curLen; - } - - return sendResult; -} - - - -PBYTE icq_httpGatewayUnwrapRecv(NETLIBHTTPREQUEST*, PBYTE buf, int len, int* outBufLen, void *(*)(void *, size_t)) -{ - size_t wLen, wType; - DWORD dwPackSeq; - PBYTE tbuf; - size_t i = 0; - - tbuf = buf; - for (;;) { - if (tbuf - buf + 2 > len) - break; - unpackWord(&tbuf, &wLen); - if (wLen < 12) - break; - if (tbuf - buf + wLen > (size_t)len) - break; - tbuf += 2; /* version */ - unpackWord(&tbuf, &wType); - tbuf += 4; /* flags */ - unpackDWord(&tbuf, &dwPackSeq); - if (wType == HTTP_PACKETTYPE_FLAP) { // it is normal data packet - size_t copyBytes = wLen - 12; - if (copyBytes > len - i) { - /* invalid data - do our best to get something out of it */ - copyBytes = len - i; - } - memcpy(buf + i, tbuf, copyBytes); - i += copyBytes; - } - else if (wType == HTTP_PACKETTYPE_LOGINREPLY) { // our "virtual connection" was established, good - BYTE bRes; - - unpackByte(&tbuf, &bRes); - wLen -= 1; - if (!bRes) - Netlib_Logf(nullptr, "Gateway Connection #%d Established.", dwPackSeq); - else - Netlib_Logf(nullptr, "Gateway Connection #%d Failed, error: %d", dwPackSeq, bRes); - } - else if (wType == HTTP_PACKETTYPE_CLOSEREPLY) { // "virtual connection" closed - only received if any other "virual connection" still active - Netlib_Logf(nullptr, "Gateway Connection #%d Closed.", dwPackSeq); - } - tbuf += wLen - 12; - } - *outBufLen = (int)i; - - return buf; -} - -int icq_httpGatewayWalkTo(HNETLIBCONN hConn, NETLIBOPENCONNECTION* nloc) -{ // this is bad simplification - for avatars to work we need to handle - // two "virtual connections" at the same time - icq_packet packet; - DWORD dwGatewaySeq = GetGatewayIndex(hConn); - - packet.wLen = 0; - write_httphdr(&packet, HTTP_PACKETTYPE_CLOSE, dwGatewaySeq); - Netlib_Send(hConn, (char*)packet.pData, packet.wLen, MSG_DUMPPROXY | MSG_NOHTTPGATEWAYWRAP); - // we closed virtual connection, open new one - dwGatewaySeq++; - SetGatewayIndex(hConn, dwGatewaySeq); - return icq_httpGatewayBegin(hConn, nloc); -} diff --git a/protocols/IcqOscarJ/src/icq_http.h b/protocols/IcqOscarJ/src/icq_http.h deleted file mode 100644 index fb593e2977..0000000000 --- a/protocols/IcqOscarJ/src/icq_http.h +++ /dev/null @@ -1,44 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000,2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001,2002 Jon Keating, Richard Hughes -// Copyright © 2002,2003,2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004,2005 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// ----------------------------------------------------------------------------- - -#ifndef __ICQ_HTTP_H -#define __ICQ_HTTP_H - -#define HTTP_PROXY_VERSION 0x0443 - -#define HTTP_PACKETTYPE_HELLOREPLY 2 -#define HTTP_PACKETTYPE_LOGIN 3 -#define HTTP_PACKETTYPE_LOGINREPLY 4 /* contains 1 byte: 0 */ -#define HTTP_PACKETTYPE_FLAP 5 -#define HTTP_PACKETTYPE_CLOSE 6 /* contains no data */ -#define HTTP_PACKETTYPE_CLOSEREPLY 7 /* contains 1 byte: 0 */ - -int icq_httpGatewayInit(HNETLIBCONN hConn, NETLIBOPENCONNECTION *nloc, NETLIBHTTPREQUEST *nlhr); -int icq_httpGatewayBegin(HNETLIBCONN hConn, NETLIBOPENCONNECTION *nloc); -int icq_httpGatewayWrapSend(HNETLIBCONN hConn, PBYTE buf, int len, int flags); -PBYTE icq_httpGatewayUnwrapRecv(NETLIBHTTPREQUEST *nlhr, PBYTE buf, int bufLen, int *outBufLen, void *(*NetlibRealloc)(void *, size_t)); -int icq_httpGatewayWalkTo(HNETLIBCONN hConn, NETLIBOPENCONNECTION* nloc); - -#endif /* __ICQ_HTTP_H */ diff --git a/protocols/IcqOscarJ/src/icq_infoupdate.cpp b/protocols/IcqOscarJ/src/icq_infoupdate.cpp deleted file mode 100644 index 461619a54a..0000000000 --- a/protocols/IcqOscarJ/src/icq_infoupdate.cpp +++ /dev/null @@ -1,333 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// Background thread for automatic update of user details -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -// Retrieve users' info -void CIcqProto::icq_InitInfoUpdate(void) -{ - // Create wait objects - hInfoQueueEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr); - if (hInfoQueueEvent) { - // Init list - for (int i = 0; i < LISTSIZE; i++) { - m_infoUpdateList[i].dwUin = 0; - m_infoUpdateList[i].hContact = NULL; - m_infoUpdateList[i].queued = 0; - } - - ForkThread(&CIcqProto::InfoUpdateThread, nullptr); - } - - bInfoPendingUsers = 0; - dwInfoActiveRequest = 0; -} - -// Returns TRUE if user was queued -// Returns FALSE if the list was full -BOOL CIcqProto::icq_QueueUser(MCONTACT hContact) -{ - if (!hInfoQueueEvent) - return FALSE; - - if (nInfoUserCount >= LISTSIZE) - return FALSE; - - int i, nChecked = 0, nFirstFree = -1; - - mir_cslock l(infoUpdateMutex); - - // Check if in list - for (i = 0; (i < LISTSIZE && nChecked < nInfoUserCount); i++) { - if (m_infoUpdateList[i].hContact) { - nChecked++; - if (m_infoUpdateList[i].hContact == hContact) - return TRUE; - } - else if (nFirstFree == -1) - nFirstFree = i; - } - if (nFirstFree == -1) - nFirstFree = i; - - // Add to list - DWORD dwUin = getContactUin(hContact); - if (dwUin) { - m_infoUpdateList[nFirstFree].dwUin = dwUin; - m_infoUpdateList[nFirstFree].hContact = hContact; - m_infoUpdateList[nFirstFree].queued = time(0); - nInfoUserCount++; - - debugLogA("Queued user %u, place %u, count %u", dwUin, nFirstFree, nInfoUserCount); - - // Notify worker thread - if (hInfoQueueEvent && bInfoUpdateEnabled) - SetEvent(hInfoQueueEvent); - } - - return TRUE; -} - -void CIcqProto::icq_DequeueUser(DWORD dwUin) -{ - if (nInfoUserCount > 0) { - int nChecked = 0; - // Check if in list - mir_cslock l(infoUpdateMutex); - for (int i = 0; (i < LISTSIZE && nChecked < nInfoUserCount); i++) { - if (m_infoUpdateList[i].dwUin) { - nChecked++; - // Remove from list - if (m_infoUpdateList[i].dwUin == dwUin) { - debugLogA("Dequeued user %u", m_infoUpdateList[i].dwUin); - - m_infoUpdateList[i].dwUin = 0; - m_infoUpdateList[i].hContact = NULL; - m_infoUpdateList[i].queued = 0; - nInfoUserCount--; - break; - } - } - } - } -} - -void CIcqProto::icq_RescanInfoUpdate() -{ - bInfoPendingUsers = 0; - /* This is here, cause we do not want to emit large number of reuqest at once, - fill queue, and let thread deal with it */ - bInfoUpdateEnabled = 0; // freeze thread - - // Queue all outdated users - for (auto &hContact : AccContacts()) - if (IsMetaInfoChanged(hContact)) // Queue user - if (!icq_QueueUser(hContact)) { // The queue is full, pause queuing contacts - bInfoPendingUsers = 1; - break; - } - - bInfoUpdateEnabled = TRUE; -} - -void CIcqProto::icq_EnableUserLookup(BOOL bEnable) -{ - bInfoUpdateEnabled = bEnable; - - // Notify worker thread - if (bInfoUpdateEnabled && hInfoQueueEvent) - SetEvent(hInfoQueueEvent); -} - -void __cdecl CIcqProto::InfoUpdateThread(void*) -{ - int i; - DWORD dwWait = WAIT_OBJECT_0; - - debugLogA("%s thread starting.", "Info-Update"); - Thread_SetName("ICQ: InfoUpdateThread"); - - bInfoUpdateRunning = TRUE; - - while (bInfoUpdateRunning) { - if (!nInfoUserCount && bInfoPendingUsers) // whole queue processed, check if more users needs updating - icq_RescanInfoUpdate(); - - if (!nInfoUserCount || !bInfoUpdateEnabled || !icqOnline()) { - dwWait = WAIT_TIMEOUT; - while (bInfoUpdateRunning && dwWait == WAIT_TIMEOUT) // wait for new work or until we should end - dwWait = ICQWaitForSingleObject(hInfoQueueEvent, 10000); - } - if (!bInfoUpdateRunning) - break; - - switch (dwWait) { - case WAIT_IO_COMPLETION: - // Possible shutdown in progress - break; - - case WAIT_OBJECT_0: - case WAIT_TIMEOUT: - // Time to check for new users - if (!bInfoUpdateEnabled) - continue; // we can't send requests now - - if (nInfoUserCount && icqOnline()) { - time_t now = time(0); - BOOL bNotReady = FALSE, bTimeOuted = FALSE; - - // Check the list, take only users that were there for at least 5sec - // wait if any user is there shorter than 5sec and not a single user is there longer than 20sec - { - mir_cslock l(infoUpdateMutex); - for (i = 0; i < LISTSIZE; i++) { - if (m_infoUpdateList[i].hContact) { - if (m_infoUpdateList[i].queued + 20 < now) { - bTimeOuted = TRUE; - break; - } - if (m_infoUpdateList[i].queued + 5 >= now) - bNotReady = TRUE; - } - } - } - - if (!bTimeOuted && bNotReady) { - SleepEx(1000, TRUE); - if (!bInfoUpdateRunning) { // need to end as fast as possible - debugLogA("%s thread ended.", "Info-Update"); - goto LBL_Exit; - } - continue; - } - - // only send another request, when the previous is completed - if (FindCookie(dwInfoActiveRequest, nullptr, nullptr)) { - debugLogA("Info-Update: Request 0x%x still in progress.", dwInfoActiveRequest); - - SleepEx(1000, TRUE); - if (!bInfoUpdateRunning) { // need to end as fast as possible - debugLogA("%s thread ended.", "Info-Update"); - goto LBL_Exit; - } - continue; - } - - debugLogA("Info-Update: Users %u in queue.", nInfoUserCount); - - // Either some user is waiting long enough, or all users are ready (waited at least the minimum time) - mir_cslockfull rlck(m_ratesMutex); - if (!m_rates) // we cannot send info request - icq is offline - break; - - WORD wGroup = m_rates->getGroupFromSNAC(ICQ_EXTENSIONS_FAMILY, ICQ_META_CLI_REQUEST); - while (m_rates->getNextRateLevel(wGroup) < m_rates->getLimitLevel(wGroup, RML_IDLE_30)) { // we are over rate, need to wait before sending - int nDelay = m_rates->getDelayToLimitLevel(wGroup, RML_IDLE_50); - - rlck.unlock(); - - debugLogA("Rates: InfoUpdate delayed %dms", nDelay); - - SleepEx(nDelay, TRUE); // do not keep things locked during sleep - if (!bInfoUpdateRunning) { // need to end as fast as possible - debugLogA("%s thread ended.", "Info-Update"); - goto LBL_Exit; - } - rlck.lock(); - if (!m_rates) // we lost connection when we slept, go away - break; - } - if (!m_rates) // we cannot send info request - icq is offline - break; - - rlck.unlock(); - - userinfo *hContactList[LISTSIZE]; - int nListIndex = 0; - BYTE *pRequestData = nullptr; - size_t nRequestSize = 0; - - mir_cslock l(infoUpdateMutex); - for (i = 0; i < LISTSIZE; i++) { - if (m_infoUpdateList[i].hContact) { - // check TS again, maybe it has been updated while we slept - if (IsMetaInfoChanged(m_infoUpdateList[i].hContact)) { - if (m_infoUpdateList[i].queued + 5 < now) { - BYTE *pItem = nullptr; - size_t nItemSize = 0; - DBVARIANT dbv = { DBVT_DELETED }; - - if (!getSetting(m_infoUpdateList[i].hContact, DBSETTING_METAINFO_TOKEN, &dbv)) { // retrieve user details using privacy token - ppackTLV(&pItem, &nItemSize, 0x96, dbv.cpbVal, dbv.pbVal); - db_free(&dbv); - } - // last updated time - ppackTLVDouble(&pItem, &nItemSize, 0x64, getSettingDouble(m_infoUpdateList[i].hContact, DBSETTING_METAINFO_TIME, 0)); - - ppackTLVUID(&pItem, &nItemSize, 0x32, m_infoUpdateList[i].dwUin, nullptr); - ppackWord(&pRequestData, &nRequestSize, (WORD)nItemSize); - ppackBuffer(&pRequestData, &nRequestSize, nItemSize, pItem); - // take a reference - SAFE_FREE((void**)&pItem); - hContactList[nListIndex++] = &m_infoUpdateList[i]; - } - } - else { - debugLogA("Dequeued absolete user %u", m_infoUpdateList[i].dwUin); - - // Dequeue user and find another one - m_infoUpdateList[i].dwUin = 0; - m_infoUpdateList[i].hContact = NULL; - nInfoUserCount--; - // continue for loop - } - } - } - - debugLogA("Request info for %u user(s).", nListIndex); - - if (!nListIndex) // no users to request info for - break; - - if (!(dwInfoActiveRequest = sendUserInfoMultiRequest(pRequestData, nRequestSize, nListIndex))) { // sending data packet failed - SAFE_FREE((void**)&pRequestData); - break; - } - SAFE_FREE((void**)&pRequestData); - - for (i = 0; i < nListIndex; i++) { // Dequeue users and go back to sleep - hContactList[i]->dwUin = 0; - hContactList[i]->hContact = NULL; - hContactList[i]->queued = 0; - nInfoUserCount--; - } - } - break; - - default: - // Something strange happened. Exit - bInfoUpdateRunning = FALSE; - break; - } - } - - debugLogA("%s thread ended.", "Info-Update"); - -LBL_Exit: - CloseHandle(hInfoQueueEvent); -} - -// Clean up before exit -void CIcqProto::icq_InfoUpdateCleanup(void) -{ - debugLogA("%s must die.", "Info-Update"); - bInfoUpdateRunning = FALSE; - if (hInfoQueueEvent) - SetEvent(hInfoQueueEvent); // break queue loop -} diff --git a/protocols/IcqOscarJ/src/icq_menu.cpp b/protocols/IcqOscarJ/src/icq_menu.cpp deleted file mode 100644 index b523706b61..0000000000 --- a/protocols/IcqOscarJ/src/icq_menu.cpp +++ /dev/null @@ -1,154 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2008 Joe Kucera, Bio -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -#include - -HGENMENU g_hContactMenuItems[3]; -HANDLE g_hContactMenuSvc[3]; - -static INT_PTR IcqMenuHandleAddServContact(WPARAM wParam, LPARAM lParam) -{ - CIcqProto* ppro = CMPlugin::getInstance(wParam); - return (ppro) ? ppro->AddServerContact(wParam, lParam) : 0; -} - -static INT_PTR IcqMenuHandleXStatusDetails(WPARAM wParam, LPARAM lParam) -{ - CIcqProto* ppro = CMPlugin::getInstance(wParam); - return (ppro) ? ppro->ShowXStatusDetails(wParam, lParam) : 0; -} - -static INT_PTR IcqMenuHandleOpenProfile(WPARAM wParam, LPARAM lParam) -{ - CIcqProto* ppro = CMPlugin::getInstance(wParam); - return (ppro) ? ppro->OpenWebProfile(wParam, lParam) : 0; -} - -static int IcqPrebuildContactMenu(WPARAM wParam, LPARAM lParam) -{ - Menu_ShowItem(g_hContactMenuItems[ICMI_ADD_TO_SERVLIST], FALSE); - Menu_ShowItem(g_hContactMenuItems[ICMI_XSTATUS_DETAILS], FALSE); - Menu_ShowItem(g_hContactMenuItems[ICMI_OPEN_PROFILE], FALSE); - - CIcqProto* ppro = CMPlugin::getInstance(wParam); - return (ppro) ? ppro->OnPreBuildContactMenu(wParam, lParam) : 0; -} - -void g_MenuInit(void) -{ - /////////////// - // Contact menu - - HookEvent(ME_CLIST_PREBUILDCONTACTMENU, IcqPrebuildContactMenu); - - // Contact menu initialization - - char str[MAXMODULELABELLENGTH], *pszDest = str + 3; - mir_strcpy(str, "ICQ"); - - CMenuItem mi(&g_plugin); - mi.pszService = str; - - // "Add to server list" - mir_strcpy(pszDest, MS_ICQ_ADDSERVCONTACT); CreateServiceFunction(str, IcqMenuHandleAddServContact); - SET_UID(mi, 0x3928ba10, 0x69bc, 0x4ec9, 0x96, 0x48, 0xa4, 0x1b, 0xbe, 0x58, 0x4a, 0x7e); - mi.name.a = LPGEN("Add to server list"); - mi.position = -2049999999; - mi.hIcolibItem = Skin_GetIconHandle(SKINICON_AUTH_ADD); - g_hContactMenuItems[ICMI_ADD_TO_SERVLIST] = Menu_AddContactMenuItem(&mi); - - // "Show custom status details" - mir_strcpy(pszDest, MS_XSTATUS_SHOWDETAILS); CreateServiceFunction(str, IcqMenuHandleXStatusDetails); - SET_UID(mi, 0x4767918b, 0x898b, 0x4cb6, 0x9c, 0x54, 0x8c, 0x56, 0x6a, 0xc4, 0xed, 0x42); - mi.name.a = LPGEN("Show custom status details"); - mi.position = -2000004999; - mi.hIcolibItem = nullptr; - g_hContactMenuItems[ICMI_XSTATUS_DETAILS] = Menu_AddContactMenuItem(&mi); - - // "Open ICQ profile" - mir_strcpy(pszDest, MS_OPEN_PROFILE); CreateServiceFunction(str, IcqMenuHandleOpenProfile); - SET_UID(mi, 0x4f006492, 0x9fe5, 0x4d10, 0x88, 0xce, 0x47, 0x53, 0xba, 0x27, 0xe9, 0xc9); - mi.name.a = LPGEN("Open ICQ profile"); - mi.position = 1000029997; - g_hContactMenuItems[ICMI_OPEN_PROFILE] = Menu_AddContactMenuItem(&mi); -} - -void g_MenuUninit(void) -{ - Menu_RemoveItem(g_hContactMenuItems[ICMI_ADD_TO_SERVLIST]); - Menu_RemoveItem(g_hContactMenuItems[ICMI_XSTATUS_DETAILS]); - Menu_RemoveItem(g_hContactMenuItems[ICMI_OPEN_PROFILE]); -} - -INT_PTR CIcqProto::OpenWebProfile(WPARAM hContact, LPARAM) -{ - Utils_OpenUrl(CMStringA(FORMAT, "http://www.icq.com/people/%d", getContactUin(hContact))); - return 0; -} - -int CIcqProto::OnPreBuildContactMenu(WPARAM hContact, LPARAM) -{ - if (hContact == NULL) - return 0; - - if (icqOnline()) { - BOOL bCtrlPressed = (GetKeyState(VK_CONTROL) & 0x8000) != 0; - - DWORD dwUin = getContactUin(hContact); - - Menu_ShowItem(m_hmiReqAuth, dwUin && (bCtrlPressed || (getByte(hContact, "Auth", 0) && getWord(hContact, DBSETTING_SERVLIST_ID, 0)))); - Menu_ShowItem(m_hmiGrantAuth, dwUin && (bCtrlPressed || getByte(hContact, "Grant", 0))); - Menu_ShowItem(m_hmiRevokeAuth, dwUin && (bCtrlPressed || (getByte("PrivacyItems", 0) && !getByte(hContact, "Grant", 0)))); - - Menu_ShowItem(g_hContactMenuItems[ICMI_ADD_TO_SERVLIST], - m_bSsiEnabled && !getWord(hContact, DBSETTING_SERVLIST_ID, 0) && - !getWord(hContact, DBSETTING_SERVLIST_IGNORE, 0) && - !db_get_b(hContact, "CList", "NotOnList", 0)); - } - - Menu_ShowItem(g_hContactMenuItems[ICMI_OPEN_PROFILE], getContactUin(hContact) != 0); - BYTE bXStatus = getContactXStatus(hContact); - - Menu_ShowItem(g_hContactMenuItems[ICMI_XSTATUS_DETAILS], m_bHideXStatusUI ? 0 : bXStatus != 0); - if (bXStatus && !m_bHideXStatusUI) { - if (bXStatus > 0 && bXStatus <= XSTATUS_COUNT) - Menu_ModifyItem(g_hContactMenuItems[ICMI_XSTATUS_DETAILS], nullptr, getXStatusIcon(bXStatus, LR_SHARED)); - else - Menu_ModifyItem(g_hContactMenuItems[ICMI_XSTATUS_DETAILS], nullptr, Skin_LoadIcon(SKINICON_OTHER_SMALLDOT)); - } - - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// OnPreBuildStatusMenu event - -int CIcqProto::OnPreBuildStatusMenu(WPARAM, LPARAM) -{ - InitXStatusItems(TRUE); - return 0; -} diff --git a/protocols/IcqOscarJ/src/icq_opts.cpp b/protocols/IcqOscarJ/src/icq_opts.cpp deleted file mode 100644 index 8296a7e415..0000000000 --- a/protocols/IcqOscarJ/src/icq_opts.cpp +++ /dev/null @@ -1,544 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -#include - -extern BOOL bPopupService; - -static const wchar_t* szLogLevelDescr[] = { - LPGENW("Display all problems"), - LPGENW("Display problems causing possible loss of data"), - LPGENW("Display explanations for disconnection"), - LPGENW("Display problems requiring user intervention"), - LPGENW("Do not display any problems (not recommended)") -}; - -static void LoadDBCheckState(CIcqProto* ppro, HWND hwndDlg, int idCtrl, const char* szSetting, BYTE bDef) -{ - CheckDlgButton(hwndDlg, idCtrl, ppro->getByte(szSetting, bDef) ? BST_CHECKED : BST_UNCHECKED); -} - -static void StoreDBCheckState(CIcqProto* ppro, HWND hwndDlg, int idCtrl, const char* szSetting) -{ - ppro->setByte(szSetting, (BYTE)IsDlgButtonChecked(hwndDlg, idCtrl)); -} - -static void OptDlgChanged(HWND hwndDlg) -{ - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// standalone option pages - -static INT_PTR CALLBACK DlgProcIcqOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - CIcqProto *ppro = (CIcqProto*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - - switch (msg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - - ppro = (CIcqProto*)lParam; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam); - { - DWORD dwUin = ppro->getContactUin(NULL); - if (dwUin) - SetDlgItemInt(hwndDlg, IDC_ICQNUM, dwUin, FALSE); - else // keep it empty when no UIN entered - SetDlgItemTextA(hwndDlg, IDC_ICQNUM, ""); - - SendDlgItemMessage(hwndDlg, IDC_PASSWORD, EM_LIMITTEXT, PASSWORDMAXLEN, 0); - - // bit of a security hole here, since it's easy to extract a password from an edit box - char pszPwd[PASSWORDMAXLEN + 1]; - if (ppro->GetUserStoredPassword(pszPwd)) - SetDlgItemTextA(hwndDlg, IDC_PASSWORD, pszPwd); - - LoadDBCheckState(ppro, hwndDlg, IDC_SSL, "SecureConnection", DEFAULT_SECURE_CONNECTION); - LoadDBCheckState(ppro, hwndDlg, IDC_MD5LOGIN, "SecureLogin", DEFAULT_SECURE_LOGIN); - LoadDBCheckState(ppro, hwndDlg, IDC_LEGACY, "LegacyFix", DEFAULT_LEGACY_FIX); - - char szServer[MAX_PATH]; - if (!ppro->getSettingStringStatic(NULL, "OscarServer", szServer, MAX_PATH)) - SetDlgItemTextA(hwndDlg, IDC_ICQSERVER, szServer); - else - SetDlgItemTextA(hwndDlg, IDC_ICQSERVER, IsDlgButtonChecked(hwndDlg, IDC_SSL) ? DEFAULT_SERVER_HOST_SSL : DEFAULT_SERVER_HOST); - - SetDlgItemInt(hwndDlg, IDC_ICQPORT, ppro->getWord("OscarPort", IsDlgButtonChecked(hwndDlg, IDC_SSL) ? DEFAULT_SERVER_PORT_SSL : DEFAULT_SERVER_PORT), FALSE); - LoadDBCheckState(ppro, hwndDlg, IDC_KEEPALIVE, "KeepAlive", DEFAULT_KEEPALIVE_ENABLED); - SendDlgItemMessage(hwndDlg, IDC_LOGLEVEL, TBM_SETRANGE, FALSE, MAKELONG(0, 4)); - SendDlgItemMessage(hwndDlg, IDC_LOGLEVEL, TBM_SETPOS, TRUE, 4 - ppro->getByte("ShowLogLevel", LOG_WARNING)); - SetDlgItemText(hwndDlg, IDC_LEVELDESCR, TranslateW(szLogLevelDescr[4 - SendDlgItemMessage(hwndDlg, IDC_LOGLEVEL, TBM_GETPOS, 0, 0)])); - ShowDlgItem(hwndDlg, IDC_RECONNECTREQD, SW_HIDE); - LoadDBCheckState(ppro, hwndDlg, IDC_NOERRMULTI, "IgnoreMultiErrorBox", 0); - } - return TRUE; - - case WM_HSCROLL: - SetDlgItemText(hwndDlg, IDC_LEVELDESCR, TranslateW(szLogLevelDescr[4 - SendDlgItemMessage(hwndDlg, IDC_LOGLEVEL, TBM_GETPOS, 0, 0)])); - OptDlgChanged(hwndDlg); - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_LOOKUPLINK: - Utils_OpenUrl(URL_FORGOT_PASSWORD); - return TRUE; - - case IDC_NEWUINLINK: - Utils_OpenUrl(URL_REGISTER); - return TRUE; - - case IDC_RESETSERVER: - SetDlgItemInt(hwndDlg, IDC_ICQPORT, IsDlgButtonChecked(hwndDlg, IDC_SSL) ? DEFAULT_SERVER_PORT_SSL : DEFAULT_SERVER_PORT, FALSE); - - case IDC_SSL: - SetDlgItemTextA(hwndDlg, IDC_ICQSERVER, IsDlgButtonChecked(hwndDlg, IDC_SSL) ? DEFAULT_SERVER_HOST_SSL : DEFAULT_SERVER_HOST); - SetDlgItemInt(hwndDlg, IDC_ICQPORT, IsDlgButtonChecked(hwndDlg, IDC_SSL) ? DEFAULT_SERVER_PORT_SSL : DEFAULT_SERVER_PORT, FALSE); - OptDlgChanged(hwndDlg); - return TRUE; - } - - if (ppro->icqOnline() && LOWORD(wParam) != IDC_NOERRMULTI) { - char szClass[80]; - GetClassNameA((HWND)lParam, szClass, sizeof(szClass)); - - if (mir_strcmpi(szClass, "EDIT") || HIWORD(wParam) == EN_CHANGE) - ShowDlgItem(hwndDlg, IDC_RECONNECTREQD, SW_SHOW); - } - - if ((LOWORD(wParam) == IDC_ICQNUM || LOWORD(wParam) == IDC_PASSWORD || LOWORD(wParam) == IDC_ICQSERVER || LOWORD(wParam) == IDC_ICQPORT) && - (HIWORD(wParam) != EN_CHANGE || (HWND)lParam != GetFocus())) { - return 0; - } - - OptDlgChanged(hwndDlg); - break; - - case WM_NOTIFY: - switch (((LPNMHDR)lParam)->code) { - case PSN_APPLY: - char str[128]; - - ppro->setDword(UNIQUEIDSETTING, GetDlgItemInt(hwndDlg, IDC_ICQNUM, nullptr, FALSE)); - GetDlgItemTextA(hwndDlg, IDC_PASSWORD, str, _countof(ppro->m_szPassword)); - if (mir_strlen(str)) { - mir_strcpy(ppro->m_szPassword, str); - ppro->m_bRememberPwd = true; - } - else ppro->m_bRememberPwd = ppro->getByte("RememberPass", 0); - ppro->setString("Password", str); - - GetDlgItemTextA(hwndDlg, IDC_ICQSERVER, str, _countof(str)); - ppro->setString("OscarServer", str); - - ppro->setWord("OscarPort", (WORD)GetDlgItemInt(hwndDlg, IDC_ICQPORT, nullptr, FALSE)); - - StoreDBCheckState(ppro, hwndDlg, IDC_KEEPALIVE, "KeepAlive"); - StoreDBCheckState(ppro, hwndDlg, IDC_SSL, "SecureConnection"); - StoreDBCheckState(ppro, hwndDlg, IDC_MD5LOGIN, "SecureLogin"); - StoreDBCheckState(ppro, hwndDlg, IDC_LEGACY, "LegacyFix"); - StoreDBCheckState(ppro, hwndDlg, IDC_NOERRMULTI, "IgnoreMultiErrorBox"); - ppro->setByte("ShowLogLevel", (BYTE)(4 - SendDlgItemMessage(hwndDlg, IDC_LOGLEVEL, TBM_GETPOS, 0, 0))); - return true; - } - break; - } - - return FALSE; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static const UINT icqPrivacyControls[] = { - IDC_DCALLOW_ANY, IDC_DCALLOW_CLIST, IDC_DCALLOW_AUTH, IDC_ADD_ANY, IDC_ADD_AUTH, - IDC_WEBAWARE, IDC_PUBLISHPRIMARY, IDC_STATIC_DC1, IDC_STATIC_DC2, IDC_STATIC_CLIST -}; - -static INT_PTR CALLBACK DlgProcIcqPrivacyOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - CIcqProto* ppro = (CIcqProto*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - - switch (msg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - - ppro = (CIcqProto*)lParam; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam); - { - int nDcType = ppro->getByte("DCType", 0); - int nAddAuth = ppro->getByte("Auth", 1); - - if (!ppro->icqOnline()) { - icq_EnableMultipleControls(hwndDlg, icqPrivacyControls, _countof(icqPrivacyControls), FALSE); - ShowDlgItem(hwndDlg, IDC_STATIC_NOTONLINE, SW_SHOW); - } - else ShowDlgItem(hwndDlg, IDC_STATIC_NOTONLINE, SW_HIDE); - - CheckDlgButton(hwndDlg, IDC_DCALLOW_ANY, (nDcType == 0) ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_DCALLOW_CLIST, (nDcType == 1) ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_DCALLOW_AUTH, (nDcType == 2) ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_ADD_ANY, (nAddAuth == 0) ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_ADD_AUTH, (nAddAuth == 1) ? BST_CHECKED : BST_UNCHECKED); - LoadDBCheckState(ppro, hwndDlg, IDC_WEBAWARE, "WebAware", 0); - LoadDBCheckState(ppro, hwndDlg, IDC_PUBLISHPRIMARY, "PublishPrimaryEmail", 0); - LoadDBCheckState(ppro, hwndDlg, IDC_STATUSMSG_CLIST, "StatusMsgReplyCList", 0); - LoadDBCheckState(ppro, hwndDlg, IDC_STATUSMSG_VISIBLE, "StatusMsgReplyVisible", 0); - if (!ppro->getByte("StatusMsgReplyCList", 0)) - EnableDlgItem(hwndDlg, IDC_STATUSMSG_VISIBLE, FALSE); - } - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_DCALLOW_ANY: - case IDC_DCALLOW_CLIST: - case IDC_DCALLOW_AUTH: - case IDC_ADD_ANY: - case IDC_ADD_AUTH: - case IDC_WEBAWARE: - case IDC_PUBLISHPRIMARY: - case IDC_STATUSMSG_VISIBLE: - if ((HWND)lParam != GetFocus()) return 0; - break; - case IDC_STATUSMSG_CLIST: - if (IsDlgButtonChecked(hwndDlg, IDC_STATUSMSG_CLIST)) { - EnableDlgItem(hwndDlg, IDC_STATUSMSG_VISIBLE, TRUE); - LoadDBCheckState(ppro, hwndDlg, IDC_STATUSMSG_VISIBLE, "StatusMsgReplyVisible", 0); - } - else { - EnableDlgItem(hwndDlg, IDC_STATUSMSG_VISIBLE, FALSE); - CheckDlgButton(hwndDlg, IDC_STATUSMSG_VISIBLE, BST_UNCHECKED); - } - break; - default: - return 0; - } - OptDlgChanged(hwndDlg); - break; - - case WM_NOTIFY: - switch (((LPNMHDR)lParam)->code) { - case PSN_APPLY: - StoreDBCheckState(ppro, hwndDlg, IDC_WEBAWARE, "WebAware"); - StoreDBCheckState(ppro, hwndDlg, IDC_PUBLISHPRIMARY, "PublishPrimaryEmail"); - StoreDBCheckState(ppro, hwndDlg, IDC_STATUSMSG_CLIST, "StatusMsgReplyCList"); - StoreDBCheckState(ppro, hwndDlg, IDC_STATUSMSG_VISIBLE, "StatusMsgReplyVisible"); - if (IsDlgButtonChecked(hwndDlg, IDC_DCALLOW_AUTH)) - ppro->setByte("DCType", 2); - else if (IsDlgButtonChecked(hwndDlg, IDC_DCALLOW_CLIST)) - ppro->setByte("DCType", 1); - else - ppro->setByte("DCType", 0); - StoreDBCheckState(ppro, hwndDlg, IDC_ADD_AUTH, "Auth"); - - if (ppro->icqOnline()) { - PBYTE buf = nullptr; - size_t buflen = 0; - - ppackTLVWord(&buf, &buflen, 0x19A, !ppro->getByte("Auth", 1)); - ppackTLVByte(&buf, &buflen, 0x212, ppro->getByte("WebAware", 0)); - ppackTLVWord(&buf, &buflen, 0x1F9, ppro->getByte("PrivacyLevel", 1)); - - ppro->icq_changeUserDirectoryInfoServ(buf, buflen, DIRECTORYREQUEST_UPDATEPRIVACY); - - SAFE_FREE((void**)&buf); - - // Send a status packet to notify the server about the webaware setting - WORD wStatus = MirandaStatusToIcq(ppro->m_iStatus); - - if (ppro->m_iStatus == ID_STATUS_INVISIBLE) { - if (ppro->m_bSsiEnabled) - ppro->updateServVisibilityCode(3); - ppro->icq_setstatus(wStatus, nullptr); - } - else { - ppro->icq_setstatus(wStatus, nullptr); - if (ppro->m_bSsiEnabled) - ppro->updateServVisibilityCode(4); - } - } - return TRUE; - } - break; - } - - return FALSE; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static HWND hCpCombo; - -struct CPTABLE -{ - int cpId; - char *cpName; -}; - -struct CPTABLE cpTable[] = { - { 874, LPGEN("Thai") }, - { 932, LPGEN("Japanese") }, - { 936, LPGEN("Simplified Chinese") }, - { 949, LPGEN("Korean") }, - { 950, LPGEN("Traditional Chinese") }, - { 1250, LPGEN("Central European") }, - { 1251, LPGEN("Cyrillic") }, - { 1252, LPGEN("Latin I") }, - { 1253, LPGEN("Greek") }, - { 1254, LPGEN("Turkish") }, - { 1255, LPGEN("Hebrew") }, - { 1256, LPGEN("Arabic") }, - { 1257, LPGEN("Baltic") }, - { 1258, LPGEN("Vietnamese") }, - { 1361, LPGEN("Korean (Johab)") }, - { -1, nullptr } -}; - -static BOOL CALLBACK FillCpCombo(LPSTR str) -{ - int i, cp = atoi(str); - for (i = 0; cpTable[i].cpName != nullptr && cpTable[i].cpId != cp; i++); - if (cpTable[i].cpName) - ComboBoxAddStringUtf(hCpCombo, cpTable[i].cpName, cpTable[i].cpId); - - return TRUE; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static const UINT icqDCMsgControls[] = { IDC_DCPASSIVE }; -static const UINT icqXStatusControls[] = { IDC_XSTATUSAUTO }; -static const UINT icqCustomStatusControls[] = { IDC_XSTATUSRESET }; - -static INT_PTR CALLBACK DlgProcIcqFeaturesOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - CIcqProto* ppro = (CIcqProto*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - - switch (msg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - - ppro = (CIcqProto*)lParam; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam); - { - LoadDBCheckState(ppro, hwndDlg, IDC_TEMPVISIBLE, "TempVisListEnabled", DEFAULT_TEMPVIS_ENABLED); - LoadDBCheckState(ppro, hwndDlg, IDC_SLOWSEND, "SlowSend", DEFAULT_SLOWSEND); - BOOL byData = ppro->getByte("DirectMessaging", DEFAULT_DCMSG_ENABLED); - CheckDlgButton(hwndDlg, IDC_DCENABLE, byData ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_DCPASSIVE, byData == 1 ? BST_CHECKED : BST_UNCHECKED); - icq_EnableMultipleControls(hwndDlg, icqDCMsgControls, _countof(icqDCMsgControls), byData ? TRUE : FALSE); - BYTE byXStatusEnabled = ppro->getByte("XStatusEnabled", DEFAULT_XSTATUS_ENABLED); - CheckDlgButton(hwndDlg, IDC_XSTATUSENABLE, byXStatusEnabled ? BST_CHECKED : BST_UNCHECKED); - BYTE byMoodsEnabled = ppro->getByte("MoodsEnabled", DEFAULT_MOODS_ENABLED); - CheckDlgButton(hwndDlg, IDC_MOODSENABLE, byMoodsEnabled ? BST_CHECKED : BST_UNCHECKED); - icq_EnableMultipleControls(hwndDlg, icqXStatusControls, _countof(icqXStatusControls), byXStatusEnabled); - icq_EnableMultipleControls(hwndDlg, icqCustomStatusControls, _countof(icqCustomStatusControls), byXStatusEnabled || byMoodsEnabled); - LoadDBCheckState(ppro, hwndDlg, IDC_XSTATUSAUTO, "XStatusAuto", DEFAULT_XSTATUS_AUTO); - LoadDBCheckState(ppro, hwndDlg, IDC_XSTATUSRESET, "XStatusReset", DEFAULT_XSTATUS_RESET); - LoadDBCheckState(ppro, hwndDlg, IDC_KILLSPAMBOTS, "KillSpambots", DEFAULT_KILLSPAM_ENABLED); - - hCpCombo = GetDlgItem(hwndDlg, IDC_UTFCODEPAGE); - int sCodePage = ppro->getWord("AnsiCodePage", CP_ACP); - ComboBoxAddStringUtf(GetDlgItem(hwndDlg, IDC_UTFCODEPAGE), LPGEN("System default codepage"), 0); - EnumSystemCodePagesA(FillCpCombo, CP_INSTALLED); - if (sCodePage == 0) - SendDlgItemMessage(hwndDlg, IDC_UTFCODEPAGE, CB_SETCURSEL, 0, 0); - else { - for (int i = 0; i < SendDlgItemMessage(hwndDlg, IDC_UTFCODEPAGE, CB_GETCOUNT, 0, 0); i++) { - if (SendDlgItemMessage(hwndDlg, IDC_UTFCODEPAGE, CB_GETITEMDATA, (WPARAM)i, 0) == sCodePage) { - SendDlgItemMessage(hwndDlg, IDC_UTFCODEPAGE, CB_SETCURSEL, (WPARAM)i, 0); - break; - } - } - } - } - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_UTFCODEPAGE: - if (HIWORD(wParam) == CBN_SELCHANGE) - OptDlgChanged(hwndDlg); - break; - case IDC_DCENABLE: - icq_EnableMultipleControls(hwndDlg, icqDCMsgControls, _countof(icqDCMsgControls), IsDlgButtonChecked(hwndDlg, IDC_DCENABLE)); - OptDlgChanged(hwndDlg); - break; - case IDC_XSTATUSENABLE: - icq_EnableMultipleControls(hwndDlg, icqXStatusControls, _countof(icqXStatusControls), IsDlgButtonChecked(hwndDlg, IDC_XSTATUSENABLE)); - case IDC_MOODSENABLE: - icq_EnableMultipleControls(hwndDlg, icqCustomStatusControls, _countof(icqCustomStatusControls), IsDlgButtonChecked(hwndDlg, IDC_XSTATUSENABLE) || IsDlgButtonChecked(hwndDlg, IDC_MOODSENABLE)); - default: - OptDlgChanged(hwndDlg); - break; - } - break; - - case WM_NOTIFY: - switch (((LPNMHDR)lParam)->code) { - case PSN_APPLY: - int i = SendDlgItemMessage(hwndDlg, IDC_UTFCODEPAGE, CB_GETCURSEL, 0, 0); - ppro->m_wAnsiCodepage = (WORD)SendDlgItemMessage(hwndDlg, IDC_UTFCODEPAGE, CB_GETITEMDATA, (WPARAM)i, 0); - ppro->setWord("AnsiCodePage", ppro->m_wAnsiCodepage); - - ppro->m_bTempVisListEnabled = (BYTE)IsDlgButtonChecked(hwndDlg, IDC_TEMPVISIBLE); - ppro->setByte("TempVisListEnabled", ppro->m_bTempVisListEnabled); - StoreDBCheckState(ppro, hwndDlg, IDC_SLOWSEND, "SlowSend"); - if (IsDlgButtonChecked(hwndDlg, IDC_DCENABLE)) - ppro->m_bDCMsgEnabled = IsDlgButtonChecked(hwndDlg, IDC_DCPASSIVE) ? 1 : 2; - else - ppro->m_bDCMsgEnabled = 0; - ppro->setByte("DirectMessaging", ppro->m_bDCMsgEnabled); - ppro->m_bXStatusEnabled = (BYTE)IsDlgButtonChecked(hwndDlg, IDC_XSTATUSENABLE); - ppro->setByte("XStatusEnabled", ppro->m_bXStatusEnabled); - ppro->m_bMoodsEnabled = (BYTE)IsDlgButtonChecked(hwndDlg, IDC_MOODSENABLE); - ppro->setByte("MoodsEnabled", ppro->m_bMoodsEnabled); - StoreDBCheckState(ppro, hwndDlg, IDC_XSTATUSAUTO, "XStatusAuto"); - StoreDBCheckState(ppro, hwndDlg, IDC_XSTATUSRESET, "XStatusReset"); - StoreDBCheckState(ppro, hwndDlg, IDC_KILLSPAMBOTS, "KillSpambots"); - return TRUE; - } - break; - } - return FALSE; -} - -static const UINT icqContactsControls[] = { IDC_ADDSERVER, IDC_LOADFROMSERVER, IDC_SAVETOSERVER, IDC_UPLOADNOW }; -static const UINT icqAvatarControls[] = { IDC_AUTOLOADAVATARS, IDC_STRICTAVATARCHECK }; - -static INT_PTR CALLBACK DlgProcIcqContactsOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - CIcqProto* ppro = (CIcqProto*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - - switch (msg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - - ppro = (CIcqProto*)lParam; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam); - - LoadDBCheckState(ppro, hwndDlg, IDC_ENABLE, "UseServerCList", DEFAULT_SS_ENABLED); - LoadDBCheckState(ppro, hwndDlg, IDC_ADDSERVER, "ServerAddRemove", DEFAULT_SS_ADDSERVER); - LoadDBCheckState(ppro, hwndDlg, IDC_LOADFROMSERVER, "LoadServerDetails", DEFAULT_SS_LOAD); - LoadDBCheckState(ppro, hwndDlg, IDC_SAVETOSERVER, "StoreServerDetails", DEFAULT_SS_STORE); - LoadDBCheckState(ppro, hwndDlg, IDC_ENABLEAVATARS, "AvatarsEnabled", DEFAULT_AVATARS_ENABLED); - LoadDBCheckState(ppro, hwndDlg, IDC_AUTOLOADAVATARS, "AvatarsAutoLoad", DEFAULT_LOAD_AVATARS); - LoadDBCheckState(ppro, hwndDlg, IDC_STRICTAVATARCHECK, "StrictAvatarCheck", DEFAULT_AVATARS_CHECK); - - icq_EnableMultipleControls(hwndDlg, icqContactsControls, _countof(icqContactsControls), ppro->getByte("UseServerCList", DEFAULT_SS_ENABLED) ? TRUE : FALSE); - icq_EnableMultipleControls(hwndDlg, icqAvatarControls, _countof(icqAvatarControls), ppro->getByte("AvatarsEnabled", DEFAULT_AVATARS_ENABLED) ? TRUE : FALSE); - - if (ppro->icqOnline()) { - ShowDlgItem(hwndDlg, IDC_OFFLINETOENABLE, SW_SHOW); - EnableDlgItem(hwndDlg, IDC_ENABLE, FALSE); - EnableDlgItem(hwndDlg, IDC_ENABLEAVATARS, FALSE); - } - else - EnableDlgItem(hwndDlg, IDC_UPLOADNOW, FALSE); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_UPLOADNOW: - ppro->ShowUploadContactsDialog(); - return TRUE; - case IDC_ENABLE: - icq_EnableMultipleControls(hwndDlg, icqContactsControls, _countof(icqContactsControls), IsDlgButtonChecked(hwndDlg, IDC_ENABLE)); - if (ppro->icqOnline()) - ShowDlgItem(hwndDlg, IDC_RECONNECTREQD, SW_SHOW); - else - EnableDlgItem(hwndDlg, IDC_UPLOADNOW, FALSE); - break; - case IDC_ENABLEAVATARS: - icq_EnableMultipleControls(hwndDlg, icqAvatarControls, _countof(icqAvatarControls), IsDlgButtonChecked(hwndDlg, IDC_ENABLEAVATARS)); - break; - } - OptDlgChanged(hwndDlg); - break; - - case WM_NOTIFY: - if (((LPNMHDR)lParam)->code == PSN_APPLY) { - StoreDBCheckState(ppro, hwndDlg, IDC_ENABLE, "UseServerCList"); - StoreDBCheckState(ppro, hwndDlg, IDC_ADDSERVER, "ServerAddRemove"); - StoreDBCheckState(ppro, hwndDlg, IDC_LOADFROMSERVER, "LoadServerDetails"); - StoreDBCheckState(ppro, hwndDlg, IDC_SAVETOSERVER, "StoreServerDetails"); - StoreDBCheckState(ppro, hwndDlg, IDC_ENABLEAVATARS, "AvatarsEnabled"); - StoreDBCheckState(ppro, hwndDlg, IDC_AUTOLOADAVATARS, "AvatarsAutoLoad"); - StoreDBCheckState(ppro, hwndDlg, IDC_STRICTAVATARCHECK, "StrictAvatarCheck"); - return TRUE; - } - break; - } - return FALSE; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -INT_PTR CALLBACK DlgProcIcqPopupOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); - -int CIcqProto::OnOptionsInit(WPARAM wParam, LPARAM) -{ - OPTIONSDIALOGPAGE odp = {}; - odp.position = -800000000; - odp.szGroup.w = LPGENW("Network"); - odp.dwInitParam = LPARAM(this); - odp.szTitle.w = m_tszUserName; - odp.flags = ODPF_BOLDGROUPS | ODPF_UNICODE | ODPF_DONTTRANSLATE; - - odp.szTab.w = LPGENW("Account"); - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_ICQ); - odp.pfnDlgProc = DlgProcIcqOpts; - g_plugin.addOptions(wParam, &odp); - - odp.szTab.w = LPGENW("Contacts"); - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_ICQCONTACTS); - odp.pfnDlgProc = DlgProcIcqContactsOpts; - g_plugin.addOptions(wParam, &odp); - - odp.szTab.w = LPGENW("Features"); - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_ICQFEATURES); - odp.pfnDlgProc = DlgProcIcqFeaturesOpts; - g_plugin.addOptions(wParam, &odp); - - odp.szTab.w = LPGENW("Privacy"); - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_ICQPRIVACY); - odp.pfnDlgProc = DlgProcIcqPrivacyOpts; - g_plugin.addOptions(wParam, &odp); - - if (bPopupService) { - odp.position = 100000000; - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_POPUPS); - odp.pfnDlgProc = DlgProcIcqPopupOpts; - odp.szGroup.w = LPGENW("Popups"); - odp.szTab.w = nullptr; - g_plugin.addOptions(wParam, &odp); - } - return 0; -} diff --git a/protocols/IcqOscarJ/src/icq_packet.cpp b/protocols/IcqOscarJ/src/icq_packet.cpp deleted file mode 100644 index bf57851409..0000000000 --- a/protocols/IcqOscarJ/src/icq_packet.cpp +++ /dev/null @@ -1,895 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera, Bio -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -WORD generate_flap_sequence() -{ - DWORD n = rand(), s = 0; - - for (DWORD i = n; i >>= 3; s += i); - - return (((0 - s) ^ (BYTE)n) & 7 ^ n) + 2; -} - -void __fastcall init_generic_packet(icq_packet *pPacket, WORD wHeaderLen) -{ - pPacket->wPlace = 0; - pPacket->wLen += wHeaderLen; - pPacket->pData = (BYTE*)SAFE_MALLOC(pPacket->wLen); -} - -void write_httphdr(icq_packet *pPacket, WORD wType, DWORD dwSeq) -{ - init_generic_packet(pPacket, 14); - - packWord(pPacket, (WORD)(pPacket->wLen - 2)); - packWord(pPacket, HTTP_PROXY_VERSION); - packWord(pPacket, wType); - packDWord(pPacket, 0); // Flags? - packDWord(pPacket, dwSeq); // Connection sequence ? -} - -void __fastcall write_flap(icq_packet *pPacket, BYTE byFlapChannel) -{ - init_generic_packet(pPacket, 6); - - pPacket->nChannel = byFlapChannel; - - packByte(pPacket, FLAP_MARKER); - packByte(pPacket, byFlapChannel); - packWord(pPacket, 0); // This is the sequence ID, it is filled in during the actual sending - packWord(pPacket, (WORD)(pPacket->wLen - 6)); // This counter should not include the flap header (thus the -6) -} - -void __fastcall serverPacketInit(icq_packet *pPacket, size_t wSize) -{ - pPacket->wLen = (WORD)wSize; - write_flap(pPacket, ICQ_DATA_CHAN); -} - -void __fastcall directPacketInit(icq_packet *pPacket, size_t dwSize) -{ - pPacket->wPlace = 0; - pPacket->wLen = (WORD)dwSize; - pPacket->pData = (BYTE *)SAFE_MALLOC(dwSize + 2); - - packLEWord(pPacket, pPacket->wLen); -} - -void __fastcall serverCookieInit(icq_packet *pPacket, BYTE *pCookie, size_t wCookieSize) -{ - pPacket->wLen = (WORD)(wCookieSize + 8 + sizeof(CLIENT_ID_STRING) + 66); - - write_flap(pPacket, ICQ_LOGIN_CHAN); - packDWord(pPacket, 0x00000001); - packTLV(pPacket, 0x06, wCookieSize, pCookie); - - // Pack client identification details. - packTLV(pPacket, 0x0003, (WORD)sizeof(CLIENT_ID_STRING) - 1, (LPBYTE)CLIENT_ID_STRING); - packTLVWord(pPacket, 0x0017, CLIENT_VERSION_MAJOR); - packTLVWord(pPacket, 0x0018, CLIENT_VERSION_MINOR); - packTLVWord(pPacket, 0x0019, CLIENT_VERSION_LESSER); - packTLVWord(pPacket, 0x001a, CLIENT_VERSION_BUILD); - packTLVWord(pPacket, 0x0016, CLIENT_ID_CODE); - packTLVDWord(pPacket, 0x0014, CLIENT_DISTRIBUTION); - packTLV(pPacket, 0x000f, 0x0002, (LPBYTE)CLIENT_LANGUAGE); - packTLV(pPacket, 0x000e, 0x0002, (LPBYTE)CLIENT_COUNTRY); - packDWord(pPacket, 0x00940001); // reconnect flag - packByte(pPacket, 0); - packTLVDWord(pPacket, 0x8003, 0x00100000); // Unknown -} - -void __fastcall packByte(icq_packet *pPacket, BYTE byValue) -{ - pPacket->pData[pPacket->wPlace++] = byValue; -} - -void __fastcall packWord(icq_packet *pPacket, WORD wValue) -{ - pPacket->pData[pPacket->wPlace++] = ((wValue & 0xff00) >> 8); - pPacket->pData[pPacket->wPlace++] = (wValue & 0x00ff); -} - -void __fastcall packDWord(icq_packet *pPacket, DWORD dwValue) -{ - pPacket->pData[pPacket->wPlace++] = (BYTE)((dwValue & 0xff000000) >> 24); - pPacket->pData[pPacket->wPlace++] = (BYTE)((dwValue & 0x00ff0000) >> 16); - pPacket->pData[pPacket->wPlace++] = (BYTE)((dwValue & 0x0000ff00) >> 8); - pPacket->pData[pPacket->wPlace++] = (BYTE)(dwValue & 0x000000ff); -} - -void __fastcall packQWord(icq_packet *pPacket, DWORD64 qwValue) -{ - packDWord(pPacket, (DWORD)(qwValue >> 32)); - packDWord(pPacket, (DWORD)(qwValue & 0xffffffff)); -} - -void packTLV(icq_packet *pPacket, WORD wType, size_t wLength, const BYTE *pbyValue) -{ - packWord(pPacket, wType); - packWord(pPacket, (WORD)wLength); - packBuffer(pPacket, pbyValue, wLength); -} - -void packTLVWord(icq_packet *pPacket, WORD wType, WORD wValue) -{ - packWord(pPacket, wType); - packWord(pPacket, 0x02); - packWord(pPacket, wValue); -} - -void packTLVDWord(icq_packet *pPacket, WORD wType, DWORD dwValue) -{ - packWord(pPacket, wType); - packWord(pPacket, 0x04); - packDWord(pPacket, dwValue); -} - - -void packTLVUID(icq_packet *pPacket, WORD wType, DWORD dwUin, const char *szUid) -{ - if (dwUin) { - char szUin[UINMAXLEN]; - - _ltoa(dwUin, szUin, 10); - - packTLV(pPacket, wType, getUINLen(dwUin), (BYTE*)szUin); - } - else if (szUid) - packTLV(pPacket, wType, mir_strlen(szUid), (BYTE*)szUid); -} - - -// Pack a preformatted buffer. -// This can be used to pack strings or any type of raw data. -void packBuffer(icq_packet *pPacket, const BYTE* pbyBuffer, size_t wLength) -{ - while (wLength) { - pPacket->pData[pPacket->wPlace++] = *pbyBuffer++; - wLength--; - } -} - -int __fastcall getUINLen(DWORD dwUin) -{ - BYTE dwUinLen = 0; - - while (dwUin) { - dwUin /= 10; - dwUinLen += 1; - } - return dwUinLen; -} - -int __fastcall getUIDLen(DWORD dwUin, const char *szUid) -{ - if (dwUin) - return getUINLen(dwUin); - - return (int)mir_strlen(szUid); -} - -void __fastcall packUIN(icq_packet *pPacket, DWORD dwUin) -{ - char pszUin[UINMAXLEN]; - BYTE nUinLen = getUINLen(dwUin); - - _ltoa(dwUin, pszUin, 10); - - packByte(pPacket, nUinLen); // Length of user id - packBuffer(pPacket, (LPBYTE)pszUin, nUinLen); // Receiving user's id -} - -void __fastcall packUID(icq_packet *pPacket, DWORD dwUin, const char *szUid) -{ - if (dwUin) - packUIN(pPacket, dwUin); - else { - BYTE nLen = (BYTE)mir_strlen(szUid); - packByte(pPacket, nLen); - packBuffer(pPacket, (LPBYTE)szUid, nLen); - } -} - - -void packFNACHeader(icq_packet *pPacket, WORD wFamily, WORD wSubtype) -{ - packFNACHeader(pPacket, wFamily, wSubtype, 0, wSubtype << 0x10); -} - - -void packFNACHeader(icq_packet *pPacket, WORD wFamily, WORD wSubtype, WORD wFlags, DWORD dwSequence) -{ - WORD wSequence = (WORD)dwSequence & 0x7FFF; // this is necessary, if that bit is there we get disconnected - - packWord(pPacket, wFamily); // Family type - packWord(pPacket, wSubtype); // Family subtype - packWord(pPacket, wFlags); // SNAC flags - packWord(pPacket, wSequence); // SNAC request id (sequence) - packWord(pPacket, (WORD)(dwSequence >> 0x10)); // SNAC request id (command) -} - - -void packFNACHeader(icq_packet *pPacket, WORD wFamily, WORD wSubtype, WORD wFlags, DWORD dwSequence, WORD wVersion) -{ - packFNACHeader(pPacket, wFamily, wSubtype, wFlags | 0x8000, dwSequence); - packWord(pPacket, 0x06); - packTLVWord(pPacket, 0x01, wVersion); -} - - -void __fastcall packLEWord(icq_packet *pPacket, WORD wValue) -{ - pPacket->pData[pPacket->wPlace++] = (wValue & 0x00ff); - pPacket->pData[pPacket->wPlace++] = ((wValue & 0xff00) >> 8); -} - -void __fastcall packLEDWord(icq_packet *pPacket, DWORD dwValue) -{ - pPacket->pData[pPacket->wPlace++] = (BYTE)(dwValue & 0x000000ff); - pPacket->pData[pPacket->wPlace++] = (BYTE)((dwValue & 0x0000ff00) >> 8); - pPacket->pData[pPacket->wPlace++] = (BYTE)((dwValue & 0x00ff0000) >> 16); - pPacket->pData[pPacket->wPlace++] = (BYTE)((dwValue & 0xff000000) >> 24); -} - - -/* helper function to place numerics to buffer */ -static void packWord(PBYTE buf, WORD wValue) -{ - *(buf) = ((wValue & 0xff00) >> 8); - *(buf + 1) = (wValue & 0x00ff); -} - - -static void packDWord(PBYTE buf, DWORD dwValue) -{ - *(buf) = (BYTE)((dwValue & 0xff000000) >> 24); - *(buf + 1) = (BYTE)((dwValue & 0x00ff0000) >> 16); - *(buf + 2) = (BYTE)((dwValue & 0x0000ff00) >> 8); - *(buf + 3) = (BYTE)(dwValue & 0x000000ff); -} - - -static void packQWord(PBYTE buf, DWORD64 qwValue) -{ - packDWord(buf, (DWORD)(qwValue >> 32)); - packDWord(buf + 4, (DWORD)(qwValue & 0xffffffff)); -} - - -void ppackByte(PBYTE *buf, size_t *buflen, BYTE byValue) -{ - *buf = (PBYTE)SAFE_REALLOC(*buf, 1 + *buflen); - *(*buf + *buflen) = byValue; - ++*buflen; -} - - -void ppackWord(PBYTE *buf, size_t *buflen, WORD wValue) -{ - *buf = (PBYTE)SAFE_REALLOC(*buf, 2 + *buflen); - packWord(*buf + *buflen, wValue); - *buflen += 2; -} - - -void ppackLEWord(PBYTE *buf, size_t *buflen, WORD wValue) -{ - *buf = (PBYTE)SAFE_REALLOC(*buf, 2 + *buflen); - *(PWORD)(*buf + *buflen) = wValue; - *buflen += 2; -} - - -void ppackLEDWord(PBYTE *buf, size_t *buflen, DWORD dwValue) -{ - *buf = (PBYTE)SAFE_REALLOC(*buf, 4 + *buflen); - *(PDWORD)(*buf + *buflen) = dwValue; - *buflen += 4; -} - - -void ppackLELNTS(PBYTE *buf, size_t *buflen, const char *str) -{ - size_t len = mir_strlen(str); - ppackLEWord(buf, buflen, (WORD)len); - *buf = (PBYTE)SAFE_REALLOC(*buf, *buflen + len); - memcpy(*buf + *buflen, str, len); - *buflen += (WORD)len; -} - - -void ppackBuffer(PBYTE *buf, size_t *buflen, size_t wLength, const BYTE *pbyValue) -{ - if (wLength) { - *buf = (PBYTE)SAFE_REALLOC(*buf, wLength + *buflen); - memcpy(*buf + *buflen, pbyValue, wLength); - *buflen += wLength; - } -} - - -void ppackTLV(PBYTE *buf, size_t *buflen, WORD wType, size_t wLength, const BYTE *pbyValue) -{ - *buf = (PBYTE)SAFE_REALLOC(*buf, 4 + wLength + *buflen); - packWord(*buf + *buflen, wType); - packWord(*buf + *buflen + 2, (WORD)wLength); - if (wLength) - memcpy(*buf + *buflen + 4, pbyValue, wLength); - *buflen += 4 + wLength; -} - - -void ppackTLVByte(PBYTE *buf, size_t *buflen, WORD wType, BYTE byValue) -{ - *buf = (PBYTE)SAFE_REALLOC(*buf, 5 + *buflen); - packWord(*buf + *buflen, wType); - packWord(*buf + *buflen + 2, 1); - *(*buf + *buflen + 4) = byValue; - *buflen += 5; -} - - -void ppackTLVWord(PBYTE *buf, size_t *buflen, WORD wType, WORD wValue) -{ - *buf = (PBYTE)SAFE_REALLOC(*buf, 6 + *buflen); - packWord(*buf + *buflen, wType); - packWord(*buf + *buflen + 2, 2); - packWord(*buf + *buflen + 4, wValue); - *buflen += 6; -} - - -void ppackTLVDWord(PBYTE *buf, size_t *buflen, WORD wType, DWORD dwValue) -{ - *buf = (PBYTE)SAFE_REALLOC(*buf, 8 + *buflen); - packWord(*buf + *buflen, wType); - packWord(*buf + *buflen + 2, 4); - packDWord(*buf + *buflen + 4, dwValue); - *buflen += 8; -} - - -void ppackTLVDouble(PBYTE *buf, size_t *buflen, WORD wType, double dValue) -{ - DWORD64 qwValue; - - memcpy(&qwValue, &dValue, 8); - - *buf = (PBYTE)SAFE_REALLOC(*buf, 12 + *buflen); - packWord(*buf + *buflen, wType); - packWord(*buf + *buflen + 2, 8); - packQWord(*buf + *buflen + 4, qwValue); - *buflen += 12; -} - - -void ppackTLVUID(PBYTE *buf, size_t *buflen, WORD wType, DWORD dwUin, const char *szUid) -{ - if (dwUin) { - char szUin[UINMAXLEN]; - - _ltoa(dwUin, szUin, 10); - - ppackTLV(buf, buflen, wType, getUINLen(dwUin), (BYTE*)szUin); - } - else if (szUid) - ppackTLV(buf, buflen, wType, mir_strlen(szUid), (BYTE*)szUid); -} - - -// *** TLV based (!!! WORDs and DWORDs are LE !!!) -void ppackLETLVByte(PBYTE *buf, size_t *buflen, BYTE byValue, WORD wType, BYTE always) -{ - if (!always && !byValue) return; - - *buf = (PBYTE)SAFE_REALLOC(*buf, 5 + *buflen); - *(PWORD)(*buf + *buflen) = wType; - *(PWORD)(*buf + *buflen + 2) = 1; - *(*buf + *buflen + 4) = byValue; - *buflen += 5; -} - - -void ppackLETLVWord(PBYTE *buf, size_t *buflen, WORD wValue, WORD wType, BYTE always) -{ - if (!always && !wValue) return; - - *buf = (PBYTE)SAFE_REALLOC(*buf, 6 + *buflen); - *(PWORD)(*buf + *buflen) = wType; - *(PWORD)(*buf + *buflen + 2) = 2; - *(PWORD)(*buf + *buflen + 4) = wValue; - *buflen += 6; -} - - -void ppackLETLVDWord(PBYTE *buf, size_t *buflen, DWORD dwValue, WORD wType, BYTE always) -{ - if (!always && !dwValue) return; - - *buf = (PBYTE)SAFE_REALLOC(*buf, 8 + *buflen); - *(PWORD)(*buf + *buflen) = wType; - *(PWORD)(*buf + *buflen + 2) = 4; - *(PDWORD)(*buf + *buflen + 4) = dwValue; - *buflen += 8; -} - - -void packLETLVLNTS(PBYTE *buf, size_t *bufpos, const char *str, WORD wType) -{ - size_t len = mir_strlen(str) + 1; - - *(PWORD)(*buf + *bufpos) = wType; - *(PWORD)(*buf + *bufpos + 2) = WORD(len + 2); - *(PWORD)(*buf + *bufpos + 4) = WORD(len); - memcpy(*buf + *bufpos + 6, str, len); - *bufpos += len + 6; -} - - -void ppackLETLVLNTS(PBYTE *buf, size_t *buflen, const char *str, WORD wType, BYTE always) -{ - size_t len = mir_strlen(str) + 1; - - if (!always && len < 2) return; - - *buf = (PBYTE)SAFE_REALLOC(*buf, 6 + *buflen + len); - packLETLVLNTS(buf, buflen, str, wType); -} - - -void ppackLETLVWordLNTS(PBYTE *buf, size_t *buflen, WORD w, const char *str, WORD wType, BYTE always) -{ - size_t len = mir_strlen(str) + 1; - - if (!always && len < 2 && !w) return; - - *buf = (PBYTE)SAFE_REALLOC(*buf, 8 + *buflen + len); - *(PWORD)(*buf + *buflen) = wType; - *(PWORD)(*buf + *buflen + 2) = WORD(len + 4); - *(PWORD)(*buf + *buflen + 4) = w; - *(PWORD)(*buf + *buflen + 6) = WORD(len); - memcpy(*buf + *buflen + 8, str, len); - *buflen += len + 8; -} - - -void ppackLETLVLNTSByte(PBYTE *buf, size_t *buflen, const char *str, BYTE b, WORD wType) -{ - size_t len = mir_strlen(str) + 1; - - *buf = (PBYTE)SAFE_REALLOC(*buf, 7 + *buflen + len); - *(PWORD)(*buf + *buflen) = wType; - *(PWORD)(*buf + *buflen + 2) = WORD(len + 3); - *(PWORD)(*buf + *buflen + 4) = WORD(len); - memcpy(*buf + *buflen + 6, str, len); - *(*buf + *buflen + 6 + len) = b; - *buflen += len + 7; -} - - -void CIcqProto::ppackLETLVLNTSfromDB(PBYTE *buf, size_t *buflen, const char *szSetting, WORD wType) -{ - char szTmp[1024]; - char *str = ""; - - if (!getSettingStringStatic(NULL, szSetting, szTmp, sizeof(szTmp))) - str = szTmp; - - ppackLETLVLNTS(buf, buflen, str, wType, 1); -} - -void CIcqProto::ppackLETLVWordLNTSfromDB(PBYTE *buf, size_t *buflen, WORD w, const char *szSetting, WORD wType) -{ - char szTmp[1024]; - char *str = ""; - - if (!getSettingStringStatic(NULL, szSetting, szTmp, sizeof(szTmp))) - str = szTmp; - - ppackLETLVWordLNTS(buf, buflen, w, str, wType, 1); -} - -void CIcqProto::ppackLETLVLNTSBytefromDB(PBYTE *buf, size_t *buflen, const char *szSetting, BYTE b, WORD wType) -{ - char szTmp[1024]; - char *str = ""; - - if (!getSettingStringStatic(NULL, szSetting, szTmp, sizeof(szTmp))) - str = szTmp; - - ppackLETLVLNTSByte(buf, buflen, str, b, wType); -} - - -void CIcqProto::ppackTLVStringFromDB(PBYTE *buf, size_t *buflen, const char *szSetting, WORD wType) -{ - char szTmp[1024]; - char *str = ""; - - if (!getSettingStringStatic(NULL, szSetting, szTmp, sizeof(szTmp))) - str = szTmp; - - ppackTLV(buf, buflen, wType, mir_strlen(str), (PBYTE)str); -} - - -void CIcqProto::ppackTLVStringUtfFromDB(PBYTE *buf, size_t *buflen, const char *szSetting, WORD wType) -{ - char *str = getSettingStringUtf(NULL, szSetting, nullptr); - - ppackTLV(buf, buflen, wType, mir_strlen(str), (PBYTE)str); - - SAFE_FREE((void**)&str); -} - - -void CIcqProto::ppackTLVDateFromDB(PBYTE *buf, size_t *buflen, const char *szSettingYear, const char *szSettingMonth, const char *szSettingDay, WORD wType) -{ - SYSTEMTIME sTime = { 0 }; - double time = 0; - - sTime.wYear = getWord(szSettingYear, 0); - sTime.wMonth = getByte(szSettingMonth, 0); - sTime.wDay = getByte(szSettingDay, 0); - if (sTime.wYear || sTime.wMonth || sTime.wDay) { - SystemTimeToVariantTime(&sTime, &time); - time -= 2; - } - - ppackTLVDouble(buf, buflen, wType, time); -} - - -int CIcqProto::ppackTLVWordStringItemFromDB(PBYTE *buf, size_t *buflen, const char *szSetting, WORD wTypeID, WORD wTypeData, WORD wID) -{ - char szTmp[1024]; - char *str = nullptr; - - if (!getSettingStringStatic(NULL, szSetting, szTmp, sizeof(szTmp))) - str = szTmp; - - if (str) { - size_t wLen = mir_strlen(str); - - ppackWord(buf, buflen, WORD(wLen + 0x0A)); - ppackTLVWord(buf, buflen, wTypeID, wID); - ppackTLV(buf, buflen, wTypeData, wLen, (PBYTE)str); - - return 1; // Success - } - - return 0; // No data -} - - -int CIcqProto::ppackTLVWordStringUtfItemFromDB(PBYTE *buf, size_t *buflen, const char *szSetting, WORD wTypeID, WORD wTypeData, WORD wID) -{ - char *str = getSettingStringUtf(NULL, szSetting, nullptr); - - if (str) { - size_t wLen = mir_strlen(str); - - ppackWord(buf, buflen, WORD(wLen + 0x0A)); - ppackTLVWord(buf, buflen, wTypeID, wID); - ppackTLV(buf, buflen, wTypeData, wLen, (PBYTE)str); - - SAFE_FREE(&str); - - return 1; // Success - } - - return 0; // No data -} - - -void ppackTLVBlockItems(PBYTE *buf, size_t *buflen, WORD wType, int *nItems, PBYTE *pBlock, WORD *wLength, BOOL bSingleItem) -{ - *buf = (PBYTE)SAFE_REALLOC(*buf, 8 + *buflen + *wLength); - packWord(*buf + *buflen, wType); - packWord(*buf + *buflen + 2, (bSingleItem ? 4 : 2) + *wLength); - packWord(*buf + *buflen + 4, *nItems); - if (bSingleItem) - packWord(*buf + *buflen + 6, *wLength); - if (*wLength) - memcpy(*buf + *buflen + (bSingleItem ? 8 : 6), *pBlock, *wLength); - *buflen += (bSingleItem ? 8 : 6) + *wLength; - - SAFE_FREE((void**)pBlock); - *wLength = 0; - *nItems = 0; -} - - -void ppackTLVBlockItem(PBYTE *buf, size_t *buflen, WORD wType, PBYTE *pItem, WORD *wLength) -{ - if (wLength) { - *buf = (PBYTE)SAFE_REALLOC(*buf, 8 + *buflen + *wLength); - packWord(*buf + *buflen, wType); - packWord(*buf + *buflen + 2, 4 + *wLength); - packWord(*buf + *buflen + 4, 1); - packWord(*buf + *buflen + 6, *wLength); - memcpy(*buf + *buflen + 8, *pItem, *wLength); - *buflen += 8 + *wLength; - *wLength = 0; - } - else { - *buf = (PBYTE)SAFE_REALLOC(*buf, 6 + *buflen); - packWord(*buf + *buflen, wType); - packWord(*buf + *buflen + 2, 0x02); - packWord(*buf + *buflen + 4, 0); - *buflen += 6; - } - - SAFE_FREE((void**)pItem); -} - - -void __fastcall unpackByte(BYTE **pSource, BYTE *byDestination) -{ - if (byDestination) - *byDestination = *(*pSource)++; - else - (*pSource)++; -} - -void __fastcall unpackWord(BYTE **pSource, WORD *wDestination) -{ - BYTE *tmp = *pSource; - - if (wDestination) { - *wDestination = *tmp++ << 8; - *wDestination |= *tmp++; - - *pSource = tmp; - } - else *pSource += 2; -} - -void __fastcall unpackWord(BYTE **pSource, size_t *wDestination) -{ - BYTE *tmp = *pSource; - - if (wDestination) { - *wDestination = *tmp++ << 8; - *wDestination |= *tmp++; - - *pSource = tmp; - } - else *pSource += 2; -} - -void __fastcall unpackDWord(BYTE **pSource, DWORD *dwDestination) -{ - BYTE *tmp = *pSource; - - if (dwDestination) { - *dwDestination = *tmp++ << 24; - *dwDestination |= *tmp++ << 16; - *dwDestination |= *tmp++ << 8; - *dwDestination |= *tmp++; - - *pSource = tmp; - } - else *pSource += 4; -} - -void __fastcall unpackQWord(BYTE **pSource, DWORD64 *qwDestination) -{ - DWORD dwData; - - if (qwDestination) { - unpackDWord(pSource, &dwData); - *qwDestination = ((DWORD64)dwData) << 32; - unpackDWord(pSource, &dwData); - *qwDestination |= dwData; - } - else - *pSource += 8; -} - -void __fastcall unpackLEWord(BYTE **buf, WORD *w) -{ - BYTE *tmp = *buf; - - if (w) { - *w = (*tmp++); - *w |= ((*tmp++) << 8); - } - else tmp += 2; - - *buf = tmp; -} - -void __fastcall unpackLEWord(BYTE **buf, size_t *w) -{ - BYTE *tmp = *buf; - - if (w) { - *w = (*tmp++); - *w |= ((*tmp++) << 8); - } - else tmp += 2; - - *buf = tmp; -} - -void __fastcall unpackLEDWord(BYTE **buf, DWORD *dw) -{ - BYTE *tmp = *buf; - - if (dw) { - *dw = (*tmp++); - *dw |= ((*tmp++) << 8); - *dw |= ((*tmp++) << 16); - *dw |= ((*tmp++) << 24); - } - else tmp += 4; - - *buf = tmp; -} - -void __fastcall unpackLEDWord(BYTE **buf, size_t *dw) -{ - BYTE *tmp = *buf; - - if (dw) { - *dw = (*tmp++); - *dw |= ((*tmp++) << 8); - *dw |= ((*tmp++) << 16); - *dw |= ((*tmp++) << 24); - } - else tmp += 4; - - *buf = tmp; -} - -void unpackString(BYTE **buf, char *string, size_t len) -{ - BYTE *tmp = *buf; - - if (string) { - while (len) /* Can have 0x00 so go by len */ - { - *string++ = *tmp++; - len--; - } - } - else - tmp += len; - - *buf = tmp; -} - -void unpackWideString(BYTE **buf, WCHAR *string, size_t len) -{ - BYTE *tmp = *buf; - - while (len > 1) { - *string = (*tmp++ << 8); - *string |= *tmp++; - - string++; - len -= 2; - } - - // We have a stray byte at the end, this means that the buffer had an odd length - // which indicates an error. - _ASSERTE(len == 0); - if (len != 0) { - // We dont copy the last byte but we still need to increase the buffer pointer - // (we assume that 'len' was correct) since the calling function expects - // that it is increased 'len' bytes. - *tmp += (BYTE)len; - } - - *buf = tmp; -} - -void unpackTypedTLV(BYTE *buf, size_t buflen, WORD type, WORD *ttype, size_t *tlen, BYTE **ttlv) -{ - WORD wType; - size_t wLen; - -NextTLV: - // Unpack type and length - unpackWord(&buf, &wType); - unpackWord(&buf, &wLen); - buflen -= 4; - - if (wType != type && buflen >= wLen + 4) { // Not the right TLV, try next - buflen -= wLen; - buf += wLen; - goto NextTLV; - } - // Check buffer size - if (wLen > buflen) wLen = buflen; - - // Make sure we have a good pointer - if (ttlv) { - if (wLen) { // Unpack and save value - *ttlv = (BYTE*)SAFE_MALLOC(wLen + 1); // Add 1 for \0 - unpackString(&buf, (char*)*ttlv, wLen); - *(*ttlv + wLen) = '\0'; - } - else - *ttlv = nullptr; - } - - // Save type and length - if (ttype) - *ttype = wType; - if (tlen) - *tlen = wLen; -} - - -BOOL CIcqProto::unpackUID(BYTE **ppBuf, size_t *pwLen, DWORD *pdwUIN, uid_str *ppszUID) -{ - // sanity check - if (!ppBuf || !pwLen || *pwLen < 1) - return FALSE; - - // Sender UIN - BYTE nUIDLen; - unpackByte(ppBuf, &nUIDLen); - *pwLen -= 1; - - if ((nUIDLen > *pwLen) || (nUIDLen == 0)) - return FALSE; - - if (nUIDLen <= UINMAXLEN) { // it can be uin, check - char szUIN[UINMAXLEN + 1]; - - unpackString(ppBuf, szUIN, nUIDLen); - szUIN[nUIDLen] = '\0'; - *pwLen -= nUIDLen; - - if (IsStringUIN(szUIN)) { - *pdwUIN = atoi(szUIN); - return TRUE; - } - else { // go back - *ppBuf -= nUIDLen; - *pwLen += nUIDLen; - } - } - if (!ppszUID || !(*ppszUID)) { // skip the UID data - *ppBuf += nUIDLen; - *pwLen -= nUIDLen; - - debugLogA("Malformed UIN in packet"); - return FALSE; - } - - unpackString(ppBuf, *ppszUID, nUIDLen); - *pwLen -= nUIDLen; - (*ppszUID)[nUIDLen] = '\0'; - - *pdwUIN = 0; // this is how we determine aim contacts internally - - return TRUE; -} diff --git a/protocols/IcqOscarJ/src/icq_packet.h b/protocols/IcqOscarJ/src/icq_packet.h deleted file mode 100644 index 21be92ed30..0000000000 --- a/protocols/IcqOscarJ/src/icq_packet.h +++ /dev/null @@ -1,120 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera, Bio -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- - -#ifndef __ICQ_PACKET_H -#define __ICQ_PACKET_H - -typedef unsigned char BYTE; -typedef unsigned short WORD; -typedef unsigned long DWORD; - -/*---------* Structures *--------------*/ - -struct icq_packet -{ - WORD wPlace; - BYTE nChannel; - WORD wLen; - BYTE *pData; -}; - -/*---------* Functions *---------------*/ - -WORD generate_flap_sequence(); - -void __fastcall init_generic_packet(icq_packet *pPacket, WORD wHeaderLen); -void write_httphdr(icq_packet *pPacket, WORD wType, DWORD dwSeq); -void __fastcall write_flap(icq_packet *pPacket, BYTE byFlapChannel); -void __fastcall serverPacketInit(icq_packet *pPacket, size_t cbSize); -void __fastcall directPacketInit(icq_packet *pPacket, size_t cbSize); - -void __fastcall serverCookieInit(icq_packet *pPacket, BYTE *pCookie, size_t wCookieSize); - -void __fastcall packByte(icq_packet *pPacket, BYTE byValue); -void __fastcall packWord(icq_packet *pPacket, WORD wValue); -void __fastcall packDWord(icq_packet *pPacket, DWORD dwValue); -void __fastcall packQWord(icq_packet *pPacket, DWORD64 qwValue); -void packTLV(icq_packet *pPacket, WORD wType, size_t wLength, const BYTE *pbyValue); -void packTLVWord(icq_packet *pPacket, WORD wType, WORD wData); -void packTLVDWord(icq_packet *pPacket, WORD wType, DWORD dwData); -void packTLVUID(icq_packet *pPacket, WORD wType, DWORD dwUin, const char *szUid); - -void packBuffer(icq_packet *pPacket, const BYTE *pbyBuffer, size_t wLength); - -int __fastcall getUINLen(DWORD dwUin); -int __fastcall getUIDLen(DWORD dwUin, const char *szUid); -void __fastcall packUIN(icq_packet *pPacket, DWORD dwUin); -void __fastcall packUID(icq_packet *pPacket, DWORD dwUin, const char *szUid); - -void packFNACHeader(icq_packet *pPacket, WORD wFamily, WORD wSubtype); -void packFNACHeader(icq_packet *pPacket, WORD wFamily, WORD wSubtype, WORD wFlags, DWORD dwSequence); -void packFNACHeader(icq_packet *pPacket, WORD wFamily, WORD wSubtype, WORD wFlags, DWORD dwSequence, WORD wVersion); - -void __fastcall packLEWord(icq_packet *pPacket, WORD wValue); -void __fastcall packLEDWord(icq_packet *pPacket, DWORD dwValue); - -void packLETLVLNTS(PBYTE *buf, size_t *bufpos, const char *str, WORD wType); - -void ppackByte(PBYTE *buf, size_t *buflen, BYTE byValue); -void ppackWord(PBYTE *buf, size_t *buflen, WORD wValue); -void ppackLEWord(PBYTE *buf, size_t *buflen, WORD wValue); -void ppackLEDWord(PBYTE *buf, size_t *buflen, DWORD dwValue); -void ppackLELNTS(PBYTE *buf, size_t *buflen, const char *str); -void ppackBuffer(PBYTE *buf, size_t *buflen, size_t wLength, const BYTE *pbyValue); - -void ppackTLV(PBYTE *buf, size_t *buflen, WORD wType, size_t wLength, const BYTE *pbyValue); -void ppackTLVByte(PBYTE *buf, size_t *buflen, WORD wType, BYTE byValue); -void ppackTLVWord(PBYTE *buf, size_t *buflen, WORD wType, WORD wValue); -void ppackTLVDWord(PBYTE *buf, size_t *buflen, WORD wType, DWORD dwValue); -void ppackTLVDouble(PBYTE *buf, size_t *buflen, WORD wType, double dValue); -void ppackTLVUID(PBYTE *buf, size_t *buflen, WORD wType, DWORD dwUin, const char *szUid); - -void ppackLETLVByte(PBYTE *buf, size_t *buflen, BYTE byValue, WORD wType, BYTE always); -void ppackLETLVWord(PBYTE *buf, size_t *buflen, WORD wValue, WORD wType, BYTE always); -void ppackLETLVDWord(PBYTE *buf, size_t *buflen, DWORD dwValue, WORD wType, BYTE always); -void ppackLETLVLNTS(PBYTE *buf, size_t *buflen, const char *str, WORD wType, BYTE always); -void ppackLETLVWordLNTS(PBYTE *buf, size_t *buflen, WORD w, const char *str, WORD wType, BYTE always); -void ppackLETLVLNTSByte(PBYTE *buf, size_t *buflen, const char *str, BYTE b, WORD wType); - -void ppackTLVBlockItems(PBYTE *buf, size_t *buflen, WORD wType, int *nItems, PBYTE *pBlock, WORD *wLength, BOOL bSingleItem); -void ppackTLVBlockItem(PBYTE *buf, size_t *buflen, WORD wType, PBYTE *pItem, WORD *wLength); - -void __fastcall unpackByte(BYTE **pSource, BYTE *byDestination); -void __fastcall unpackWord(BYTE **pSource, WORD *wDestination); -void __fastcall unpackWord(BYTE **pSource, size_t *wDestination); -void __fastcall unpackDWord(BYTE **pSource, DWORD *dwDestination); -void __fastcall unpackQWord(BYTE **pSource, DWORD64 *qwDestination); -void unpackString(BYTE **buf, char *string, size_t len); -void unpackWideString(BYTE **buf, WCHAR *string, size_t len); -void unpackTypedTLV(BYTE *buf, size_t buflen, WORD type, WORD *ttype, size_t *tlen, BYTE **ttlv); -BOOL unpackUID(BYTE **ppBuf, WORD *pwLen, DWORD *pdwUIN, uid_str *ppszUID); - -void __fastcall unpackLEWord(BYTE **buf, WORD *w); -void __fastcall unpackLEWord(BYTE **buf, size_t *w); - -void __fastcall unpackLEDWord(BYTE **buf, DWORD *dw); -void __fastcall unpackLEDWord(BYTE **buf, size_t *dw); - -#endif /* __ICQ_PACKET_H */ diff --git a/protocols/IcqOscarJ/src/icq_popups.cpp b/protocols/IcqOscarJ/src/icq_popups.cpp deleted file mode 100644 index 2e824c9ff1..0000000000 --- a/protocols/IcqOscarJ/src/icq_popups.cpp +++ /dev/null @@ -1,279 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2008 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// Popup Plugin stuff -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -extern BOOL bPopupService; - -static const UINT icqPopupsControls[] = { - IDC_POPUPS_LOG_ENABLED, IDC_POPUPS_SPAM_ENABLED, IDC_PREVIEW, IDC_USESYSICONS, IDC_POPUP_LOG0_TIMEOUT, - IDC_POPUP_LOG1_TIMEOUT, IDC_POPUP_LOG2_TIMEOUT, IDC_POPUP_LOG3_TIMEOUT, IDC_POPUP_SPAM_TIMEOUT -}; - -static const UINT icqPopupColorControls[] = { - IDC_POPUP_LOG0_TEXTCOLOR, IDC_POPUP_LOG1_TEXTCOLOR, IDC_POPUP_LOG2_TEXTCOLOR, IDC_POPUP_LOG3_TEXTCOLOR, IDC_POPUP_SPAM_TEXTCOLOR, - IDC_POPUP_LOG0_BACKCOLOR, IDC_POPUP_LOG1_BACKCOLOR, IDC_POPUP_LOG2_BACKCOLOR, IDC_POPUP_LOG3_BACKCOLOR, IDC_POPUP_SPAM_BACKCOLOR -}; - -INT_PTR CALLBACK DlgProcIcqPopupOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - static bool bInitDone = true; - BYTE bEnabled; - CIcqProto* ppro = (CIcqProto*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - - switch (msg) { - case WM_INITDIALOG: - bInitDone = false; - TranslateDialogDefault(hwndDlg); - - ppro = (CIcqProto*)lParam; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam); - - CheckDlgButton(hwndDlg, IDC_POPUPS_LOG_ENABLED, ppro->getByte(NULL, "PopupsLogEnabled", DEFAULT_LOG_POPUPS_ENABLED) ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_POPUPS_SPAM_ENABLED, ppro->getByte(NULL, "PopupsSpamEnabled", DEFAULT_SPAM_POPUPS_ENABLED) ? BST_CHECKED : BST_UNCHECKED); - SendDlgItemMessage(hwndDlg, IDC_POPUP_LOG0_TEXTCOLOR, CPM_SETCOLOUR, 0, ppro->getDword(NULL, "Popups0TextColor", DEFAULT_LOG0_TEXT_COLORS)); - SendDlgItemMessage(hwndDlg, IDC_POPUP_LOG0_BACKCOLOR, CPM_SETCOLOUR, 0, ppro->getDword(NULL, "Popups0BackColor", DEFAULT_LOG0_BACK_COLORS)); - SetDlgItemInt(hwndDlg, IDC_POPUP_LOG0_TIMEOUT, ppro->getDword(NULL, "Popups0Timeout", DEFAULT_LOG0_TIMEOUT), FALSE); - SendDlgItemMessage(hwndDlg, IDC_POPUP_LOG1_TEXTCOLOR, CPM_SETCOLOUR, 0, ppro->getDword(NULL, "Popups1TextColor", DEFAULT_LOG1_TEXT_COLORS)); - SendDlgItemMessage(hwndDlg, IDC_POPUP_LOG1_BACKCOLOR, CPM_SETCOLOUR, 0, ppro->getDword(NULL, "Popups1BackColor", DEFAULT_LOG1_BACK_COLORS)); - SetDlgItemInt(hwndDlg, IDC_POPUP_LOG1_TIMEOUT, ppro->getDword(NULL, "Popups1Timeout", DEFAULT_LOG1_TIMEOUT), FALSE); - SendDlgItemMessage(hwndDlg, IDC_POPUP_LOG2_TEXTCOLOR, CPM_SETCOLOUR, 0, ppro->getDword(NULL, "Popups2TextColor", DEFAULT_LOG2_TEXT_COLORS)); - SendDlgItemMessage(hwndDlg, IDC_POPUP_LOG2_BACKCOLOR, CPM_SETCOLOUR, 0, ppro->getDword(NULL, "Popups2BackColor", DEFAULT_LOG2_BACK_COLORS)); - SetDlgItemInt(hwndDlg, IDC_POPUP_LOG2_TIMEOUT, ppro->getDword(NULL, "Popups2Timeout", DEFAULT_LOG2_TIMEOUT), FALSE); - SendDlgItemMessage(hwndDlg, IDC_POPUP_LOG3_TEXTCOLOR, CPM_SETCOLOUR, 0, ppro->getDword(NULL, "Popups3TextColor", DEFAULT_LOG3_TEXT_COLORS)); - SendDlgItemMessage(hwndDlg, IDC_POPUP_LOG3_BACKCOLOR, CPM_SETCOLOUR, 0, ppro->getDword(NULL, "Popups3BackColor", DEFAULT_LOG3_BACK_COLORS)); - SetDlgItemInt(hwndDlg, IDC_POPUP_LOG3_TIMEOUT, ppro->getDword(NULL, "Popups3Timeout", DEFAULT_LOG3_TIMEOUT), FALSE); - SendDlgItemMessage(hwndDlg, IDC_POPUP_SPAM_TEXTCOLOR, CPM_SETCOLOUR, 0, ppro->getDword(NULL, "PopupsSpamTextColor", DEFAULT_SPAM_TEXT_COLORS)); - SendDlgItemMessage(hwndDlg, IDC_POPUP_SPAM_BACKCOLOR, CPM_SETCOLOUR, 0, ppro->getDword(NULL, "PopupsSpamBackColor", DEFAULT_SPAM_BACK_COLORS)); - SetDlgItemInt(hwndDlg, IDC_POPUP_SPAM_TIMEOUT, ppro->getDword(NULL, "PopupsSpamTimeout", DEFAULT_SPAM_TIMEOUT), FALSE); - bEnabled = ppro->getByte(NULL, "PopupsWinColors", DEFAULT_POPUPS_WIN_COLORS); - CheckDlgButton(hwndDlg, IDC_USEWINCOLORS, bEnabled ? BST_CHECKED : BST_UNCHECKED); - bEnabled |= ppro->getByte(NULL, "PopupsDefColors", DEFAULT_POPUPS_DEF_COLORS); - CheckDlgButton(hwndDlg, IDC_USEDEFCOLORS, bEnabled ? BST_CHECKED : BST_UNCHECKED); - icq_EnableMultipleControls(hwndDlg, icqPopupColorControls, _countof(icqPopupColorControls), bEnabled); - CheckDlgButton(hwndDlg, IDC_USESYSICONS, ppro->getByte(NULL, "PopupsSysIcons", DEFAULT_POPUPS_SYS_ICONS) ? BST_CHECKED : BST_UNCHECKED); - bEnabled = ppro->getByte(NULL, "PopupsEnabled", DEFAULT_POPUPS_ENABLED); - CheckDlgButton(hwndDlg, IDC_POPUPS_ENABLED, bEnabled ? BST_CHECKED : BST_UNCHECKED); - icq_EnableMultipleControls(hwndDlg, icqPopupsControls, _countof(icqPopupsControls), bEnabled); - if (bEnabled) { - if (IsDlgButtonChecked(hwndDlg, IDC_USEDEFCOLORS)) { - EnableWindow(GetDlgItem(hwndDlg, IDC_USEWINCOLORS), !WM_ENABLE); - EnableWindow(GetDlgItem(hwndDlg, IDC_USEDEFCOLORS), WM_ENABLE); - } - else { - EnableWindow(GetDlgItem(hwndDlg, IDC_USEWINCOLORS), WM_ENABLE); - EnableWindow(GetDlgItem(hwndDlg, IDC_USEDEFCOLORS), !WM_ENABLE); - } - } - icq_EnableMultipleControls(hwndDlg, icqPopupColorControls, _countof(icqPopupColorControls), bEnabled & (BST_UNCHECKED == IsDlgButtonChecked(hwndDlg, IDC_USEWINCOLORS) && BST_UNCHECKED == IsDlgButtonChecked(hwndDlg, IDC_USEDEFCOLORS))); - bInitDone = true; - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_PREVIEW: - { - ppro->ShowPopupMsg(NULL, LPGEN("Popup Title"), LPGEN("Sample Note"), LOG_NOTE); - ppro->ShowPopupMsg(NULL, LPGEN("Popup Title"), LPGEN("Sample Warning"), LOG_WARNING); - ppro->ShowPopupMsg(NULL, LPGEN("Popup Title"), LPGEN("Sample Error"), LOG_ERROR); - ppro->ShowPopupMsg(NULL, LPGEN("Popup Title"), LPGEN("Sample Fatal"), LOG_FATAL); - ppro->ShowPopupMsg(NULL, LPGEN("Popup Title"), LPGEN("Sample Spambot"), POPTYPE_SPAM); - } - return FALSE; - - case IDC_POPUPS_ENABLED: - bEnabled = IsDlgButtonChecked(hwndDlg, IDC_POPUPS_ENABLED); - if (bEnabled) { - if (IsDlgButtonChecked(hwndDlg, IDC_USEDEFCOLORS)) { - EnableWindow(GetDlgItem(hwndDlg, IDC_USEWINCOLORS), !WM_ENABLE); - EnableWindow(GetDlgItem(hwndDlg, IDC_USEDEFCOLORS), WM_ENABLE); - } - else { - EnableWindow(GetDlgItem(hwndDlg, IDC_USEWINCOLORS), WM_ENABLE); - EnableWindow(GetDlgItem(hwndDlg, IDC_USEDEFCOLORS), !WM_ENABLE); - } - } - else { - EnableWindow(GetDlgItem(hwndDlg, IDC_USEWINCOLORS), !WM_ENABLE); - EnableWindow(GetDlgItem(hwndDlg, IDC_USEDEFCOLORS), !WM_ENABLE); - } - icq_EnableMultipleControls(hwndDlg, icqPopupsControls, _countof(icqPopupsControls), bEnabled); - - case IDC_USEWINCOLORS: - bEnabled = IsDlgButtonChecked(hwndDlg, IDC_POPUPS_ENABLED); - if (bEnabled) { - if (IsDlgButtonChecked(hwndDlg, IDC_USEWINCOLORS)) - EnableWindow(GetDlgItem(hwndDlg, IDC_USEDEFCOLORS), !WM_ENABLE); - else - EnableWindow(GetDlgItem(hwndDlg, IDC_USEDEFCOLORS), WM_ENABLE); - } - icq_EnableMultipleControls(hwndDlg, icqPopupColorControls, _countof(icqPopupColorControls), !IsDlgButtonChecked(hwndDlg, IDC_USEWINCOLORS)); - - case IDC_USEDEFCOLORS: - bEnabled = IsDlgButtonChecked(hwndDlg, IDC_POPUPS_ENABLED); - if (bEnabled) { - if (IsDlgButtonChecked(hwndDlg, IDC_USEDEFCOLORS)) - EnableWindow(GetDlgItem(hwndDlg, IDC_USEWINCOLORS), !WM_ENABLE); - else - EnableWindow(GetDlgItem(hwndDlg, IDC_USEWINCOLORS), WM_ENABLE); - } - icq_EnableMultipleControls(hwndDlg, icqPopupColorControls, _countof(icqPopupColorControls), !IsDlgButtonChecked(hwndDlg, IDC_USEDEFCOLORS)); - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - break; - - case IDC_POPUP_LOG0_TIMEOUT: - case IDC_POPUP_LOG1_TIMEOUT: - case IDC_POPUP_LOG2_TIMEOUT: - case IDC_POPUP_LOG3_TIMEOUT: - case IDC_POPUP_SPAM_TIMEOUT: - if ((HIWORD(wParam) == EN_CHANGE) && bInitDone) - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - break; - default: - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - break; - } - break; - - case WM_NOTIFY: - switch (((LPNMHDR)lParam)->code) { - case PSN_APPLY: - ppro->setByte("PopupsEnabled", (BYTE)IsDlgButtonChecked(hwndDlg, IDC_POPUPS_ENABLED)); - ppro->setByte("PopupsLogEnabled", (BYTE)IsDlgButtonChecked(hwndDlg, IDC_POPUPS_LOG_ENABLED)); - ppro->setByte("PopupsSpamEnabled", (BYTE)IsDlgButtonChecked(hwndDlg, IDC_POPUPS_SPAM_ENABLED)); - ppro->setDword("Popups0TextColor", SendDlgItemMessage(hwndDlg, IDC_POPUP_LOG0_TEXTCOLOR, CPM_GETCOLOUR, 0, 0)); - ppro->setDword("Popups0BackColor", SendDlgItemMessage(hwndDlg, IDC_POPUP_LOG0_BACKCOLOR, CPM_GETCOLOUR, 0, 0)); - ppro->setDword("Popups0Timeout", GetDlgItemInt(hwndDlg, IDC_POPUP_LOG0_TIMEOUT, nullptr, FALSE)); - ppro->setDword("Popups1TextColor", SendDlgItemMessage(hwndDlg, IDC_POPUP_LOG1_TEXTCOLOR, CPM_GETCOLOUR, 0, 0)); - ppro->setDword("Popups1BackColor", SendDlgItemMessage(hwndDlg, IDC_POPUP_LOG1_BACKCOLOR, CPM_GETCOLOUR, 0, 0)); - ppro->setDword("Popups1Timeout", GetDlgItemInt(hwndDlg, IDC_POPUP_LOG1_TIMEOUT, nullptr, FALSE)); - ppro->setDword("Popups2TextColor", SendDlgItemMessage(hwndDlg, IDC_POPUP_LOG2_TEXTCOLOR, CPM_GETCOLOUR, 0, 0)); - ppro->setDword("Popups2BackColor", SendDlgItemMessage(hwndDlg, IDC_POPUP_LOG2_BACKCOLOR, CPM_GETCOLOUR, 0, 0)); - ppro->setDword("Popups2Timeout", GetDlgItemInt(hwndDlg, IDC_POPUP_LOG2_TIMEOUT, nullptr, FALSE)); - ppro->setDword("Popups3TextColor", SendDlgItemMessage(hwndDlg, IDC_POPUP_LOG3_TEXTCOLOR, CPM_GETCOLOUR, 0, 0)); - ppro->setDword("Popups3BackColor", SendDlgItemMessage(hwndDlg, IDC_POPUP_LOG3_BACKCOLOR, CPM_GETCOLOUR, 0, 0)); - ppro->setDword("Popups3Timeout", GetDlgItemInt(hwndDlg, IDC_POPUP_LOG3_TIMEOUT, nullptr, FALSE)); - ppro->setDword("PopupsSpamTextColor", SendDlgItemMessage(hwndDlg, IDC_POPUP_SPAM_TEXTCOLOR, CPM_GETCOLOUR, 0, 0)); - ppro->setDword("PopupsSpamBackColor", SendDlgItemMessage(hwndDlg, IDC_POPUP_SPAM_BACKCOLOR, CPM_GETCOLOUR, 0, 0)); - ppro->setDword("PopupsSpamTimeout", GetDlgItemInt(hwndDlg, IDC_POPUP_SPAM_TIMEOUT, nullptr, FALSE)); - ppro->setByte("PopupsWinColors", (BYTE)IsDlgButtonChecked(hwndDlg, IDC_USEWINCOLORS)); - ppro->setByte("PopupsDefColors", (BYTE)IsDlgButtonChecked(hwndDlg, IDC_USEDEFCOLORS)); - ppro->setByte("PopupsSysIcons", (BYTE)IsDlgButtonChecked(hwndDlg, IDC_USESYSICONS)); - return TRUE; - } - break; - } - return FALSE; -} - -int CIcqProto::ShowPopupMsg(MCONTACT hContact, const char *szTitle, const char *szMsg, BYTE bType) -{ - if (bPopupService && getByte("PopupsEnabled", DEFAULT_POPUPS_ENABLED)) { - POPUPDATAT ppd = { 0 }; - LPWSTR rsIcon; - char szPrefix[32], szSetting[32]; - mir_strcpy(szPrefix, "Popups"); - - switch (bType) { - case LOG_NOTE: - rsIcon = IDI_INFORMATION; - ppd.colorBack = DEFAULT_LOG0_BACK_COLORS; - ppd.colorText = DEFAULT_LOG0_TEXT_COLORS; - mir_strcat(szPrefix, "0"); - break; - - case LOG_WARNING: - rsIcon = IDI_WARNING; - ppd.colorBack = DEFAULT_LOG1_BACK_COLORS; - ppd.colorText = DEFAULT_LOG1_TEXT_COLORS; - mir_strcat(szPrefix, "1"); - break; - - case LOG_ERROR: - rsIcon = IDI_ERROR; - ppd.colorBack = DEFAULT_LOG2_BACK_COLORS; - ppd.colorText = DEFAULT_LOG2_TEXT_COLORS; - mir_strcat(szPrefix, "2"); - break; - - case LOG_FATAL: - rsIcon = IDI_ERROR; - ppd.colorBack = DEFAULT_LOG3_BACK_COLORS; - ppd.colorText = DEFAULT_LOG3_TEXT_COLORS; - mir_strcat(szPrefix, "3"); - break; - - case POPTYPE_SPAM: - rsIcon = IDI_WARNING; - ppd.colorBack = DEFAULT_SPAM_BACK_COLORS; - ppd.colorText = DEFAULT_SPAM_TEXT_COLORS; - mir_strcat(szPrefix, "Spam"); - break; - - default: - return -1; - } - - if (!getByte("PopupsSysIcons", DEFAULT_POPUPS_SYS_ICONS)) - ppd.lchIcon = IcoLib_GetIconByHandle(m_hProtoIcon); - else - ppd.lchIcon = (HICON)LoadImageW(nullptr, rsIcon, IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED); - - if (getByte("PopupsWinColors", DEFAULT_POPUPS_WIN_COLORS)) { - ppd.colorText = GetSysColor(COLOR_WINDOWTEXT); - ppd.colorBack = GetSysColor(COLOR_WINDOW); - } - else { - if (getByte("PopupsDefColors", DEFAULT_POPUPS_DEF_COLORS)) { - ppd.colorText = NULL; - ppd.colorBack = NULL; - } - else { - mir_strcpy(szSetting, szPrefix); - mir_strcat(szSetting, "TextColor"); - ppd.colorText = getDword(szSetting, ppd.colorText); - mir_strcpy(szSetting, szPrefix); - mir_strcat(szSetting, "BackColor"); - ppd.colorBack = getDword(szSetting, ppd.colorBack); - } - } - mir_strcpy(szSetting, szPrefix); - mir_strcat(szSetting, "Timeout"); - ppd.iSeconds = getDword(szSetting, ppd.iSeconds); - - char str[4096]; - make_unicode_string_static(ICQTranslateUtfStatic(szTitle, str, sizeof(str)), ppd.lpwzContactName, MAX_CONTACTNAME); - make_unicode_string_static(ICQTranslateUtfStatic(szMsg, str, sizeof(str)), ppd.lpwzText, MAX_SECONDLINE); - ppd.lchContact = hContact; - ppd.PluginWindowProc = nullptr; - ppd.PluginData = nullptr; - return PUAddPopupT(&ppd); - } - return -1; // Failure -} diff --git a/protocols/IcqOscarJ/src/icq_popups.h b/protocols/IcqOscarJ/src/icq_popups.h deleted file mode 100644 index 319ffb6529..0000000000 --- a/protocols/IcqOscarJ/src/icq_popups.h +++ /dev/null @@ -1,41 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2008 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// Headers for Popup Plugin support -// -// ----------------------------------------------------------------------------- -#ifndef __ICQ_POPUPS_H -#define __ICQ_POPUPS_H - - -#define POPTYPE_SPAM 254 // this is for spambots - -int ModuleLoad(WPARAM, LPARAM); -void InitPopupOpts(WPARAM wParam); - - -#endif /* __ICQ_POPUPS_H */ diff --git a/protocols/IcqOscarJ/src/icq_proto.cpp b/protocols/IcqOscarJ/src/icq_proto.cpp deleted file mode 100644 index bc33862ae0..0000000000 --- a/protocols/IcqOscarJ/src/icq_proto.cpp +++ /dev/null @@ -1,1819 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera, George Hazan -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// Protocol Interface Implementation -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -#include "m_icolib.h" - -#pragma warning(disable:4355) - -static int CompareConns(const directconnect *p1, const directconnect *p2) -{ - if (p1 < p2) - return -1; - - return (p1 == p2) ? 0 : 1; -} - -static int CompareCookies(const icq_cookie_info *p1, const icq_cookie_info *p2) -{ - if (p1->dwCookie < p2->dwCookie) - return -1; - - return (p1->dwCookie == p2->dwCookie) ? 0 : 1; -} - -static int CompareFT(const filetransfer *p1, const filetransfer *p2) -{ - if (p1->dwCookie < p2->dwCookie) - return -1; - - return (p1->dwCookie == p2->dwCookie) ? 0 : 1; -} - -static int CompareContactsCache(const icq_contacts_cache *p1, const icq_contacts_cache *p2) -{ - if (p1->dwUin < p2->dwUin) - return -1; - - if (p1->dwUin > p2->dwUin) - return 1; - - return mir_strcmpi(p1->szUid, p2->szUid); -} - -CIcqProto::CIcqProto(const char* aProtoName, const wchar_t* aUserName) : - PROTO(aProtoName, aUserName), - cookies(10, CompareCookies), - directConns(10, CompareConns), - expectedFileRecvs(10, CompareFT), - contactsCache(10, CompareContactsCache), - CustomCapList(1), - cheekySearchId(-1), - m_arAvatars(5), - m_arFileTransfers(1) -{ - debugLogA("Setting protocol/module name to '%s'", m_szModuleName); - - // Initialize server lists - HookProtoEvent(ME_CLIST_GROUPCHANGE, &CIcqProto::ServListCListGroupChange); - HookProtoEvent(ME_DB_CONTACT_SETTINGCHANGED, &CIcqProto::ServListDbSettingChanged); - - // Initialize status message struct - memset(&m_modeMsgs, 0, sizeof(icq_mode_messages)); - - m_modeMsgsEvent = CreateProtoEvent(ME_ICQ_STATUSMSGREQ); - - // Initialize cookies - wCookieSeq = 2; - - // Initialize temporary DB settings - db_set_resident(m_szModuleName, "TemporaryVisible"); - db_set_resident(m_szModuleName, "TickTS"); - db_set_resident(m_szModuleName, "IdleTS"); - db_set_resident(m_szModuleName, "AwayTS"); - db_set_resident(m_szModuleName, "LogonTS"); - db_set_resident(m_szModuleName, "DCStatus"); - db_set_resident(m_szModuleName, "CapBuf"); //capabilities bufer - db_set_resident(m_szModuleName, DBSETTING_STATUS_NOTE_TIME); - db_set_resident(m_szModuleName, DBSETTING_STATUS_MOOD); - - // Setup services - CreateProtoService(PS_CREATEACCMGRUI, &CIcqProto::OnCreateAccMgrUI); - CreateProtoService(MS_ICQ_SENDSMS, &CIcqProto::SendSms); - CreateProtoService(PS_SETMYNICKNAME, &CIcqProto::SetNickName); - - CreateProtoService(PS_GETMYAWAYMSG, &CIcqProto::GetMyAwayMsg); - - CreateProtoService(PS_GETINFOSETTING, &CIcqProto::GetInfoSetting); - - CreateProtoService(PSS_ADDED, &CIcqProto::SendYouWereAdded); - - // ChangeInfo API - CreateProtoService(PS_CHANGEINFOEX, &CIcqProto::ChangeInfoEx); - - // Avatar API - CreateProtoService(PS_GETAVATARINFO, &CIcqProto::GetAvatarInfo); - CreateProtoService(PS_GETAVATARCAPS, &CIcqProto::GetAvatarCaps); - CreateProtoService(PS_GETMYAVATAR, &CIcqProto::GetMyAvatar); - CreateProtoService(PS_SETMYAVATAR, &CIcqProto::SetMyAvatar); - - // Custom Status API - CreateProtoService(PS_SETCUSTOMSTATUSEX, &CIcqProto::SetXStatusEx); - CreateProtoService(PS_GETCUSTOMSTATUSEX, &CIcqProto::GetXStatusEx); - CreateProtoService(PS_GETCUSTOMSTATUSICON, &CIcqProto::GetXStatusIcon); - CreateProtoService(PS_GETADVANCEDSTATUSICON, &CIcqProto::RequestAdvStatusIconIdx); - CreateProtoService(PS_ICQ_REQUESTCUSTOMSTATUS, &CIcqProto::RequestXStatusDetails); - - CreateProtoService(MS_ICQ_ADDSERVCONTACT, &CIcqProto::AddServerContact); - - CreateProtoService(PS_MENU_REQAUTH, &CIcqProto::RequestAuthorization); - CreateProtoService(PS_MENU_GRANTAUTH, &CIcqProto::GrantAuthorization); - CreateProtoService(PS_MENU_REVOKEAUTH, &CIcqProto::RevokeAuthorization); - - CreateProtoService(MS_XSTATUS_SHOWDETAILS, &CIcqProto::ShowXStatusDetails); - - // Custom caps - CreateProtoService(PS_ICQ_ADDCAPABILITY, &CIcqProto::IcqAddCapability); - CreateProtoService(PS_ICQ_CHECKCAPABILITY, &CIcqProto::IcqCheckCapability); - - // Reset a bunch of session specific settings - UpdateGlobalSettings(); - ResetSettingsOnLoad(); - - // Initialize Contacts Cache - InitContactsCache(); - - HookProtoEvent(ME_CLIST_PREBUILDSTATUSMENU, &CIcqProto::OnPreBuildStatusMenu); - HookProtoEvent(ME_OPT_INITIALISE, &CIcqProto::OnOptionsInit); - - // Register netlib users - wchar_t szBuffer[MAX_PATH + 64]; - mir_snwprintf(szBuffer, TranslateT("%s server connection"), m_tszUserName); - - NETLIBUSER nlu = {}; - nlu.flags = NUF_OUTGOING | NUF_HTTPCONNS | NUF_UNICODE; - nlu.szDescriptiveName.w = szBuffer; - nlu.szSettingsModule = m_szModuleName; - nlu.szHttpGatewayHello = "http://http.proxy.icq.com/hello"; - nlu.szHttpGatewayUserAgent = NETLIB_USER_AGENT; - nlu.pfnHttpGatewayInit = icq_httpGatewayInit; - nlu.pfnHttpGatewayBegin = icq_httpGatewayBegin; - nlu.pfnHttpGatewayWrapSend = icq_httpGatewayWrapSend; - nlu.pfnHttpGatewayUnwrapRecv = icq_httpGatewayUnwrapRecv; - m_hNetlibUser = Netlib_RegisterUser(&nlu); - - char szP2PModuleName[MAX_PATH]; - mir_snprintf(szP2PModuleName, "%sP2P", m_szModuleName); - mir_snwprintf(szBuffer, TranslateT("%s client-to-client connections"), m_tszUserName); - nlu.flags = NUF_OUTGOING | NUF_INCOMING | NUF_UNICODE; - nlu.szDescriptiveName.w = szBuffer; - nlu.szSettingsModule = szP2PModuleName; - nlu.minIncomingPorts = 1; - m_hDirectNetlibUser = Netlib_RegisterUser(&nlu); - - // Register custom database events - DBEVENTTYPEDESCR eventType = { sizeof(eventType) }; - eventType.eventType = ICQEVENTTYPE_MISSEDMESSAGE; - eventType.module = m_szModuleName; - eventType.descr = "Missed message notifications"; - eventType.textService = ICQ_DB_GETEVENTTEXT_MISSEDMESSAGE; - eventType.flags = DETF_HISTORY | DETF_MSGWINDOW; - // for now keep default "message" icon - DbEvent_RegisterType(&eventType); - - // Protocol instance is ready - debugLogA("%s: Protocol instance '%s' created.", ICQ_PROTOCOL_NAME, m_szModuleName); -} - -CIcqProto::~CIcqProto() -{ - m_bXStatusEnabled = 10; // block clist changing - m_bMoodsEnabled = 10; - - // Serv-list update board clean-up - FlushServerIDs(); - /// TODO: make sure server-list handler thread is not running - /// TODO: save state of server-list update board to DB - servlistPendingFlushOperations(); - SAFE_FREE((void**)&servlistQueueList); - - // Finalize avatars - for (auto &it : m_arAvatars) - delete it; - - // NetLib clean-up - Netlib_CloseHandle(m_hDirectNetlibUser); - Netlib_CloseHandle(m_hNetlibUser); - - // Destroy hookable events - if (m_modeMsgsEvent) - DestroyHookableEvent(m_modeMsgsEvent); - - // Clean-up remaining protocol instance members - UninitContactsCache(); - - SAFE_FREE(&m_modeMsgs.szOnline); - SAFE_FREE(&m_modeMsgs.szAway); - SAFE_FREE(&m_modeMsgs.szNa); - SAFE_FREE(&m_modeMsgs.szOccupied); - SAFE_FREE(&m_modeMsgs.szDnd); - SAFE_FREE(&m_modeMsgs.szFfc); - - debugLogA("%s: Protocol instance '%s' destroyed.", ICQ_PROTOCOL_NAME, m_szModuleName); -} - -//////////////////////////////////////////////////////////////////////////////////////// -// OnModulesLoadedEx - performs hook registration - -void CIcqProto::OnModulesLoaded() -{ - char pszP2PName[MAX_PATH]; - char pszGroupsName[MAX_PATH]; - char pszSrvGroupsName[MAX_PATH]; - char* modules[5] = { nullptr, nullptr, nullptr, nullptr, nullptr }; - - mir_snprintf(pszP2PName, "%sP2P", m_szModuleName); - mir_snprintf(pszGroupsName, "%sGroups", m_szModuleName); - mir_snprintf(pszSrvGroupsName, "%sSrvGroups", m_szModuleName); - modules[0] = m_szModuleName; - modules[1] = pszP2PName; - modules[2] = pszGroupsName; - modules[3] = pszSrvGroupsName; - CallService("DBEditorpp/RegisterModule", (WPARAM)modules, (LPARAM)4); - - // Startup Auto Info-Update thread - icq_InitInfoUpdate(); - - HookProtoEvent(ME_USERINFO_INITIALISE, &CIcqProto::OnUserInfoInit); - HookProtoEvent(ME_IDLE_CHANGED, &CIcqProto::OnIdleChanged); - - // Init extra optional modules - ModuleLoad(0, 0); - InitXStatusItems(FALSE); - - for (auto &hContact : AccContacts()) { - DWORD bXStatus = getContactXStatus(hContact); - if (bXStatus > 0) - setContactExtraIcon(hContact, bXStatus); - } -} - -void CIcqProto::OnShutdown() -{ - // signal info update thread to stop - icq_InfoUpdateCleanup(); - - // Make sure all connections are closed - CloseContactDirectConns(NULL); -} - -//////////////////////////////////////////////////////////////////////////////////////// -// PS_AddToList - adds a contact to the contact list - -MCONTACT CIcqProto::AddToList(int flags, PROTOSEARCHRESULT *psr) -{ - if (psr == nullptr) return 0; - - char szUid[MAX_PATH]; - if (psr->cbSize == sizeof(ICQSEARCHRESULT)) { - ICQSEARCHRESULT *isr = (ICQSEARCHRESULT*)psr; - if (isr->uin) - return AddToListByUIN(isr->uin, flags); - - // aim contact - if (isr->hdr.flags & PSR_UNICODE) - unicode_to_ansi_static((WCHAR*)isr->hdr.id.w, szUid, MAX_PATH); - else - null_strcpy(szUid, (char*)isr->hdr.id.w, MAX_PATH); - - return (szUid[0] == 0) ? 0 : AddToListByUID(szUid, flags); - } - - if (psr->flags & PSR_UNICODE) - unicode_to_ansi_static((WCHAR*)psr->id.w, szUid, MAX_PATH); - else - null_strcpy(szUid, (char*)psr->id.w, MAX_PATH); - - if (szUid[0] == 0) - return 0; - if (IsStringUIN(szUid)) - return AddToListByUIN(atoi(szUid), flags); - return AddToListByUID(szUid, flags); -} - -MCONTACT CIcqProto::AddToListByEvent(int flags, int iContact, MEVENT hDbEvent) -{ - DWORD uin = 0; - uid_str uid = { 0 }; - - DBEVENTINFO dbei = {}; - if ((dbei.cbBlob = db_event_getBlobSize(hDbEvent)) == -1) - return 0; - - dbei.pBlob = (PBYTE)_alloca(dbei.cbBlob + 1); - dbei.pBlob[dbei.cbBlob] = '\0'; - - if (db_event_get(hDbEvent, &dbei)) - return 0; // failed to get event - - if (mir_strcmp(dbei.szModule, m_szModuleName)) - return 0; // this event is not ours - - switch (dbei.eventType) { - case EVENTTYPE_CONTACTS: - { - char *pbOffset = (char*)dbei.pBlob; - char *pbEnd = pbOffset + dbei.cbBlob; - for (int i = 0; i <= iContact; i++) { - pbOffset += mir_strlen(pbOffset) + 1; // Nick - if (pbOffset >= pbEnd) break; - if (i == iContact) { // we found the contact, get uid - if (IsStringUIN((char*)pbOffset)) - uin = atoi((char*)pbOffset); - else { - uin = 0; - mir_strcpy(uid, (char*)pbOffset); - } - } - pbOffset += mir_strlen(pbOffset) + 1; // Uin - if (pbOffset >= pbEnd) break; - } - } - break; - - case EVENTTYPE_AUTHREQUEST: - case EVENTTYPE_ADDED: - if (!getContactUid(DbGetAuthEventContact(&dbei), &uin, &uid)) - break; - - default: - return 0; - } - - if (uin != 0) - return AddToListByUIN(uin, flags); // Success - - // add aim contact - if (mir_strlen(uid)) - return AddToListByUID(uid, flags); // Success - - return NULL; // Failure -} - - -//////////////////////////////////////////////////////////////////////////////////////// -// PS_AuthAllow - processes the successful authorization - -int CIcqProto::Authorize(MEVENT hDbEvent) -{ - if (icqOnline() && hDbEvent) { - MCONTACT hContact = HContactFromAuthEvent(hDbEvent); - if (hContact == INVALID_CONTACT_ID) - return 1; - - DWORD uin; - uid_str uid; - if (getContactUid(hContact, &uin, &uid)) - return 1; - - icq_sendAuthResponseServ(uin, uid, 1, L""); - - delSetting(hContact, "Grant"); - - return 0; // Success - } - - return 1; // Failure -} - - -//////////////////////////////////////////////////////////////////////////////////////// -// PS_AuthDeny - handles the unsuccessful authorization - -int CIcqProto::AuthDeny(MEVENT hDbEvent, const wchar_t* szReason) -{ - if (icqOnline() && hDbEvent) { - MCONTACT hContact = HContactFromAuthEvent(hDbEvent); - if (hContact == INVALID_CONTACT_ID) - return 1; - - DWORD uin; - uid_str uid; - if (getContactUid(hContact, &uin, &uid)) - return 1; - - icq_sendAuthResponseServ(uin, uid, 0, szReason); - - if (db_get_b(hContact, "CList", "NotOnList", 0)) - db_delete_contact(hContact); - - return 0; // Success - } - - return 1; // Failure -} - - -//////////////////////////////////////////////////////////////////////////////////////// -// PSR_AUTH - -int CIcqProto::AuthRecv(MCONTACT hContact, PROTORECVEVENT* pre) -{ - setContactHidden(hContact, 0); - ICQAddRecvEvent(NULL, EVENTTYPE_AUTHREQUEST, pre, pre->lParam, (PBYTE)pre->szMessage, 0); - return 0; -} - -//////////////////////////////////////////////////////////////////////////////////////// -// PSS_AUTHREQUEST - -int CIcqProto::AuthRequest(MCONTACT hContact, const wchar_t* szMessage) -{ - if (!icqOnline()) - return 1; - - if (hContact) { - DWORD dwUin; - uid_str szUid; - if (getContactUid(hContact, &dwUin, &szUid)) - return 1; // Invalid contact - - if (dwUin) { - char *utf = make_utf8_string(szMessage); - icq_sendAuthReqServ(dwUin, szUid, utf); - SAFE_FREE(&utf); - return 0; // Success - } - } - - return 1; // Failure -} - - -//////////////////////////////////////////////////////////////////////////////////////// -// PS_FileAllow - starts a file transfer - -HANDLE CIcqProto::FileAllow(MCONTACT hContact, HANDLE hTransfer, const wchar_t* szPath) -{ - DWORD dwUin; - uid_str szUid; - if (getContactUid(hContact, &dwUin, &szUid)) - return nullptr; // Invalid contact - - if (icqOnline() && hContact && szPath && hTransfer) { // approve old fashioned file transfer - basic_filetransfer *bft = (basic_filetransfer *)hTransfer; - - if (!IsValidFileTransfer(bft)) - return nullptr; // Invalid transfer - - if (dwUin && bft->ft_magic == FT_MAGIC_ICQ) { - filetransfer *ft = (filetransfer *)hTransfer; - ft->szSavePath = make_utf8_string(szPath); - { - mir_cslock l(expectedFileRecvMutex); - expectedFileRecvs.insert(ft); - } - - // Was request received thru DC and have we a open DC, send through that - if (ft->bDC && IsDirectConnectionOpen(hContact, DIRECTCONN_STANDARD, 0)) - icq_sendFileAcceptDirect(hContact, ft); - else - icq_sendFileAcceptServ(dwUin, ft, 0); - - return hTransfer; // Success - } - else if (bft->ft_magic == FT_MAGIC_OSCAR) { // approve oscar file transfer - return oftFileAllow(hContact, hTransfer, szPath); - } - } - - return nullptr; // Failure -} - - -//////////////////////////////////////////////////////////////////////////////////////// -// PS_FileCancel - cancels a file transfer - -int CIcqProto::FileCancel(MCONTACT hContact, HANDLE hTransfer) -{ - DWORD dwUin; - uid_str szUid; - if (getContactUid(hContact, &dwUin, &szUid)) - return 1; // Invalid contact - - if (hContact && hTransfer) { - basic_filetransfer *ft = (basic_filetransfer *)hTransfer; - - if (!IsValidFileTransfer(ft)) - return 1; // Invalid transfer - - if (dwUin && ft->ft_magic == FT_MAGIC_ICQ) { // cancel old fashioned file transfer - icq_CancelFileTransfer((filetransfer*)hTransfer); - return 0; // Success - } - if (ft->ft_magic == FT_MAGIC_OSCAR) { // cancel oscar file transfer - return oftFileCancel(hContact, hTransfer); - } - } - - return 1; // Failure -} - - -//////////////////////////////////////////////////////////////////////////////////////// -// PS_FileDeny - denies a file transfer - -int CIcqProto::FileDeny(MCONTACT hContact, HANDLE hTransfer, const wchar_t* szReason) -{ - int nReturnValue = 1; - basic_filetransfer *bft = (basic_filetransfer*)hTransfer; - - DWORD dwUin; - uid_str szUid; - if (getContactUid(hContact, &dwUin, &szUid)) - return 1; // Invalid contact - - if (icqOnline() && hTransfer && hContact) { - if (!IsValidFileTransfer((basic_filetransfer*)hTransfer)) - return 1; // Invalid transfer - - if (dwUin && bft->ft_magic == FT_MAGIC_ICQ) { // deny old fashioned file transfer - filetransfer *ft = (filetransfer*)hTransfer; - char *szReasonUtf = make_utf8_string(szReason); - // Was request received thru DC and have we a open DC, send through that - if (ft->bDC && IsDirectConnectionOpen(hContact, DIRECTCONN_STANDARD, 0)) - icq_sendFileDenyDirect(hContact, ft, szReasonUtf); - else - icq_sendFileDenyServ(dwUin, ft, szReasonUtf, 0); - SAFE_FREE(&szReasonUtf); - - nReturnValue = 0; // Success - } - else if (bft->ft_magic == FT_MAGIC_OSCAR) { // deny oscar file transfer - return oftFileDeny(hContact, hTransfer, szReason); - } - } - // Release possible orphan structure - SafeReleaseFileTransfer(&bft); - - return nReturnValue; -} - - -//////////////////////////////////////////////////////////////////////////////////////// -// PS_FileResume - processes file renaming etc - -int CIcqProto::FileResume(HANDLE hTransfer, int* action, const wchar_t** szFilename) -{ - if (icqOnline() && hTransfer) { - basic_filetransfer *ft = (basic_filetransfer *)hTransfer; - - if (!IsValidFileTransfer(ft)) - return 1; // Invalid transfer - - if (ft->ft_magic == FT_MAGIC_ICQ) { - char *szFileNameUtf = make_utf8_string(*szFilename); - icq_sendFileResume((filetransfer *)hTransfer, *action, szFileNameUtf); - SAFE_FREE(&szFileNameUtf); - } - else if (ft->ft_magic == FT_MAGIC_OSCAR) { - oftFileResume((oscar_filetransfer *)hTransfer, *action, *szFilename); - } - else - return 1; // Failure - - return 0; // Success - } - - return 1; // Failure -} - - -//////////////////////////////////////////////////////////////////////////////////////// -// GetCaps - return protocol capabilities bits - -INT_PTR CIcqProto::GetCaps(int type, MCONTACT hContact) -{ - INT_PTR nReturn = 0; - - switch (type) { - - case PFLAGNUM_1: - nReturn = PF1_IM | PF1_URL | PF1_AUTHREQ | PF1_BASICSEARCH | PF1_ADDSEARCHRES | - PF1_VISLIST | PF1_INVISLIST | PF1_MODEMSG | PF1_FILE | PF1_EXTSEARCH | - PF1_EXTSEARCHUI | PF1_SEARCHBYEMAIL | PF1_SEARCHBYNAME | - PF1_ADDED | PF1_CONTACT; - - if (m_bSsiEnabled && getByte("ServerAddRemove", DEFAULT_SS_ADDSERVER)) - nReturn |= PF1_SERVERCLIST; - break; - - case PFLAGNUM_2: - return PF2_ONLINE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND | PF2_HEAVYDND | - PF2_FREECHAT | PF2_INVISIBLE | PF2_ONTHEPHONE; - - case PFLAGNUM_3: - return PF2_ONLINE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND | PF2_HEAVYDND | - PF2_FREECHAT | PF2_INVISIBLE; - - case PFLAGNUM_4: - nReturn = PF4_SUPPORTIDLE | PF4_IMSENDOFFLINE | PF4_INFOSETTINGSVC | PF4_SUPPORTTYPING; - if (m_bAvatarsEnabled) - nReturn |= PF4_AVATARS; - break; - - case PFLAGNUM_5: - return PF2_FREECHAT | PF2_ONTHEPHONE; - - case PFLAG_UNIQUEIDTEXT: - return (INT_PTR)Translate("User ID"); - - case PFLAG_MAXLENOFMESSAGE: - return MAX_MESSAGESNACSIZE - 102; - - case PFLAG_MAXCONTACTSPERPACKET: - if (hContact == 0) - return MAX_CONTACTSSEND; - - // determine per contact - BYTE bClientId = getByte(hContact, "ClientID", CLID_GENERIC); - - if (bClientId == CLID_MIRANDA) { - if (CheckContactCapabilities(hContact, CAPF_CONTACTS) && getContactStatus(hContact) != ID_STATUS_OFFLINE) - return 0x100; // limited only by packet size - return MAX_CONTACTSSEND; - } - else if (bClientId == CLID_ICQ6) { - // crapy ICQ6 cannot handle multiple contacts in the transfer - return CheckContactCapabilities(hContact, CAPF_CONTACTS) != 0; - } - return MAX_CONTACTSSEND; - } - - return nReturn; -} - -//////////////////////////////////////////////////////////////////////////////////////// -// GetInfo - retrieves a contact info - -int CIcqProto::GetInfo(MCONTACT hContact, int infoType) -{ - if (icqOnline()) { - DWORD dwUin; - uid_str szUid; - if (getContactUid(hContact, &dwUin, &szUid)) - return 1; // Invalid contact - - DWORD dwCookie; - if (dwUin) - dwCookie = icq_sendGetInfoServ(hContact, dwUin, (infoType & SGIF_ONOPEN) != 0); - else // TODO: this needs something better - dwCookie = icq_sendGetAimProfileServ(hContact, szUid); - - return (dwCookie) ? 0 : 1; - } - - return 1; // Failure -} - -//////////////////////////////////////////////////////////////////////////////////////// -// SearchBasic - searches the contact by UID - -void CIcqProto::CheekySearchThread(void*) -{ - char szUin[UINMAXLEN]; - ICQSEARCHRESULT isr = { 0 }; - isr.hdr.cbSize = sizeof(isr); - - Thread_SetName("ICQ: CheekySearchThread"); - - if (cheekySearchUin) { - _itoa(cheekySearchUin, szUin, 10); - isr.hdr.id.w = (wchar_t*)szUin; - } - else { - isr.hdr.id.w = (wchar_t*)cheekySearchUid; - } - isr.uin = cheekySearchUin; - - ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)cheekySearchId, (LPARAM)&isr); - ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)cheekySearchId, 0); - cheekySearchId = -1; -} - - -HANDLE CIcqProto::SearchBasic(const wchar_t *pszSearch) -{ - if (mir_wstrlen(pszSearch) == 0) - return nullptr; - - char pszUIN[255]; - int nHandle = 0; - size_t i, j; - - for (i = j = 0; (i < mir_wstrlen(pszSearch)) && (j < 255); i++) { // we remove spaces and slashes - if ((pszSearch[i] != 0x20) && (pszSearch[i] != '-')) { - if (pszSearch[i] >= 0x80) continue; - pszUIN[j] = pszSearch[i]; - j++; - } - } - pszUIN[j] = 0; - - if (mir_strlen(pszUIN)) { - DWORD dwUin; - if (IsStringUIN(pszUIN)) - dwUin = atoi(pszUIN); - else - dwUin = 0; - - // Cheeky instant UIN search - if (!dwUin || GetKeyState(VK_CONTROL) & 0x8000) { - cheekySearchId = GenerateCookie(0); - cheekySearchUin = dwUin; - cheekySearchUid = null_strdup(pszUIN); - ForkThread(&CIcqProto::CheekySearchThread, nullptr); // The caller needs to get this return value before the results - nHandle = cheekySearchId; - } - else if (icqOnline()) { - nHandle = SearchByUin(dwUin); - } - - // Success - return (HANDLE)nHandle; - } - - // Failure - return nullptr; -} - -//////////////////////////////////////////////////////////////////////////////////////// -// SearchByEmail - searches the contact by its e-mail - -HANDLE CIcqProto::SearchByEmail(const wchar_t *email) -{ - if (email && icqOnline() && mir_wstrlen(email) > 0) { - char *szEmail = unicode_to_ansi(email); - - // Success - DWORD dwSearchId = SearchByMail(szEmail); - DWORD dwSecId = (dwSearchId == 0) ? icq_searchAimByEmail(szEmail, dwSearchId) : 0; - - SAFE_FREE(&szEmail); - - if (dwSearchId) - return (HANDLE)dwSearchId; - else - return (HANDLE)dwSecId; - } - - return nullptr; // Failure -} - -//////////////////////////////////////////////////////////////////////////////////////// -// PS_SearchByName - searches the contact by its first or last name, or by a nickname - -HANDLE CIcqProto::SearchByName(const wchar_t *nick, const wchar_t *firstName, const wchar_t *lastName) -{ - if (icqOnline()) { - if (nick || firstName || lastName) { - char *nickUtf = make_utf8_string(nick); - char *firstNameUtf = make_utf8_string(firstName); - char *lastNameUtf = make_utf8_string(lastName); - - // Success - HANDLE dwCookie = (HANDLE)SearchByNames(nickUtf, firstNameUtf, lastNameUtf, 0); - - SAFE_FREE(&nickUtf); - SAFE_FREE(&firstNameUtf); - SAFE_FREE(&lastNameUtf); - - return dwCookie; - } - } - - return nullptr; // Failure -} - - -HWND CIcqProto::CreateExtendedSearchUI(HWND parent) -{ - if (parent && g_plugin.getInst()) - return CreateDialog(g_plugin.getInst(), MAKEINTRESOURCE(IDD_ICQADVANCEDSEARCH), parent, AdvancedSearchDlgProc); - - return nullptr; // Failure -} - -HWND CIcqProto::SearchAdvanced(HWND hwndDlg) -{ - if (icqOnline() && IsWindow(hwndDlg)) { - size_t nDataLen; - BYTE* bySearchData; - - if (bySearchData = createAdvancedSearchStructure(hwndDlg, &nDataLen)) { - int result = icq_sendAdvancedSearchServ(bySearchData, nDataLen); - SAFE_FREE((void**)&bySearchData); - return (HWND)result; // Success - } - } - - return nullptr; // Failure -} - - -//////////////////////////////////////////////////////////////////////////////////////// -// RecvContacts - -int CIcqProto::RecvContacts(MCONTACT hContact, PROTORECVEVENT* pre) -{ - ICQSEARCHRESULT **isrList = (ICQSEARCHRESULT**)pre->szMessage; - int i; - size_t cbBlob = 0; - DWORD flags = DBEF_UTF; - - for (i = 0; i < pre->lParam; i++) { - cbBlob += mir_strlen((char*)isrList[i]->hdr.nick.w) + 2; // both trailing zeros - if (isrList[i]->uin) - cbBlob += getUINLen(isrList[i]->uin); - else - cbBlob += mir_strlen((char*)isrList[i]->hdr.id.w); - } - PBYTE pBlob = (PBYTE)_alloca(cbBlob), pCurBlob; - for (i = 0, pCurBlob = pBlob; i < pre->lParam; i++) { - mir_strcpy((char*)pCurBlob, (char*)isrList[i]->hdr.nick.w); - pCurBlob += mir_strlen((char*)pCurBlob) + 1; - if (isrList[i]->uin) { - char szUin[UINMAXLEN]; - _itoa(isrList[i]->uin, szUin, 10); - mir_strcpy((char*)pCurBlob, szUin); - } - else // aim contact - mir_strcpy((char*)pCurBlob, (char*)isrList[i]->hdr.id.w); - - pCurBlob += mir_strlen((char*)pCurBlob) + 1; - } - - ICQAddRecvEvent(hContact, EVENTTYPE_CONTACTS, pre, cbBlob, pBlob, flags); - return 0; -} - - -//////////////////////////////////////////////////////////////////////////////////////// -// RecvMsg - -MEVENT CIcqProto::RecvMsg(MCONTACT hContact, PROTORECVEVENT* pre) -{ - size_t cbBlob = mir_strlen(pre->szMessage) + 1; - ICQAddRecvEvent(hContact, EVENTTYPE_MESSAGE, pre, cbBlob, (PBYTE)pre->szMessage, DBEF_UTF); - - // stop contact from typing - some clients do not sent stop notify - if (CheckContactCapabilities(hContact, CAPF_TYPING)) - CallService(MS_PROTO_CONTACTISTYPING, hContact, PROTOTYPE_CONTACTTYPING_OFF); - - return 0; -} - - -//////////////////////////////////////////////////////////////////////////////////////// -// SendContacts - -int CIcqProto::SendContacts(MCONTACT hContact, int, int nContacts, MCONTACT *hContactsList) -{ - if (hContact && hContactsList) { - DWORD dwUin; - uid_str szUid; - if (getContactUid(hContact, &dwUin, &szUid)) // Invalid contact - return ReportGenericSendError(hContact, ACKTYPE_CONTACTS, "The receiver has an invalid user ID."); - - WORD wRecipientStatus = getContactStatus(hContact); - - // Failures - DWORD dwCookie; - if (!icqOnline()) - dwCookie = ReportGenericSendError(hContact, ACKTYPE_CONTACTS, "You cannot send messages when you are offline."); - else if (!hContactsList || (nContacts < 1) || (nContacts > MAX_CONTACTSSEND)) - dwCookie = ReportGenericSendError(hContact, ACKTYPE_CONTACTS, "Bad data (internal error #1)"); - else { // OK - if (CheckContactCapabilities(hContact, CAPF_CONTACTS) && wRecipientStatus != ID_STATUS_OFFLINE) { // Use the new format if possible - struct icq_contactsend_s* contacts = nullptr; - - // Format the data part and the names part - // This is kinda messy, but there is no simple way to do it. First - // we need to calculate the length of the packet. - contacts = (struct icq_contactsend_s*)_alloca(sizeof(struct icq_contactsend_s)*nContacts); - memset(contacts, 0, (sizeof(struct icq_contactsend_s) * nContacts)); - - size_t nDataLen = 0, nNamesLen = 0; - int i; - for (i = 0; i < nContacts; i++) { - uid_str szContactUid; - - if (!IsICQContact(hContactsList[i])) - break; // Abort if a non icq contact is found - if (getContactUid(hContactsList[i], &contacts[i].uin, &szContactUid)) - break; // Abort if invalid contact - contacts[i].uid = contacts[i].uin ? nullptr : null_strdup(szContactUid); - contacts[i].szNick = NickFromHandleUtf(hContactsList[i]); - nDataLen += getUIDLen(contacts[i].uin, contacts[i].uid) + 4; - nNamesLen += mir_strlen(contacts[i].szNick) + 8; - } - - if (i == nContacts) { - debugLogA("Sending contacts to %s.", strUID(dwUin, szUid)); - - // Do not calculate the exact size of the data packet - only the maximal size (easier) - // Sumarize size of group information - // - we do not utilize the full power of the protocol and send all contacts with group "General" - // just like ICQ6 does - nDataLen += 9; - nNamesLen += 9; - - // Create data structures - icq_packet mData, mNames; - mData.wPlace = 0; - mData.pData = (LPBYTE)SAFE_MALLOC(nDataLen); - mData.wLen = WORD(nDataLen); - mNames.wPlace = 0; - mNames.pData = (LPBYTE)SAFE_MALLOC(nNamesLen); - - // pack Group Name - packWord(&mData, 7); - packBuffer(&mData, (LPBYTE)"General", 7); - packWord(&mNames, 7); - packBuffer(&mNames, (LPBYTE)"General", 7); - - // all contacts in one group - packWord(&mData, WORD(nContacts)); - packWord(&mNames, WORD(nContacts)); - for (i = 0; i < nContacts; i++) { - uid_str szContactUid; - if (contacts[i].uin) - strUID(contacts[i].uin, szContactUid); - else - mir_strcpy(szContactUid, contacts[i].uid); - - // prepare UID - size_t wLen = mir_strlen(szContactUid); - packWord(&mData, WORD(wLen)); - packBuffer(&mData, (LPBYTE)szContactUid, wLen); - - // prepare Nick - wLen = mir_strlen(contacts[i].szNick); - packWord(&mNames, WORD(wLen + 4)); - packTLV(&mNames, 0x01, wLen, (LPBYTE)contacts[i].szNick); - } - - // Cleanup temporary list - for (i = 0; i < nContacts; i++) { - SAFE_FREE(&contacts[i].szNick); - SAFE_FREE(&contacts[i].uid); - } - - // Rate check - if (IsServerOverRate(ICQ_MSG_FAMILY, ICQ_MSG_SRV_SEND, RML_LIMIT)) { // rate is too high, the message will not go thru... - SAFE_FREE((void**)&mData.pData); - SAFE_FREE((void**)&mNames.pData); - - return ReportGenericSendError(hContact, ACKTYPE_CONTACTS, "The message could not be delivered. You are sending too fast. Wait a while and try again."); - } - - // Set up the ack type - cookie_message_data *pCookieData = CreateMessageCookieData(MTYPE_CONTACTS, hContact, dwUin, FALSE); - - // AIM clients do not send acknowledgement - if (!dwUin && pCookieData->nAckType == ACKTYPE_CLIENT) - pCookieData->nAckType = ACKTYPE_SERVER; - // Send the message - dwCookie = icq_SendChannel2Contacts(dwUin, szUid, hContact, (char*)mData.pData, mData.wPlace, (char*)mNames.pData, mNames.wPlace, pCookieData); - - // This will stop the message dialog from waiting for the real message delivery ack - if (pCookieData->nAckType == ACKTYPE_NONE) { - SendProtoAck(hContact, dwCookie, ACKRESULT_SUCCESS, ACKTYPE_CONTACTS, nullptr); - // We need to free this here since we will never see the real ack - // The actual cookie value will still have to be returned to the message dialog though - ReleaseCookie(dwCookie); - } - // Release our buffers - SAFE_FREE((void**)&mData.pData); - SAFE_FREE((void**)&mNames.pData); - } - else { - dwCookie = ReportGenericSendError(hContact, ACKTYPE_CONTACTS, "Bad data (internal error #2)"); - } - - for (i = 0; i < nContacts; i++) { - SAFE_FREE(&contacts[i].szNick); - SAFE_FREE(&contacts[i].uid); - } - } - else if (dwUin) { // old format is only understood by ICQ clients - char szContactUin[UINMAXLEN]; - char szCount[17]; - struct icq_contactsend_s* contacts = nullptr; - uid_str szContactUid; - int i; - - // Format the body - // This is kinda messy, but there is no simple way to do it. First - // we need to calculate the length of the packet. - contacts = (struct icq_contactsend_s*)_alloca(sizeof(struct icq_contactsend_s)*nContacts); - memset(contacts, 0, (sizeof(struct icq_contactsend_s) * nContacts)); - { - size_t nBodyLength = 0; - for (i = 0; i < nContacts; i++) { - if (!IsICQContact(hContactsList[i])) - break; // Abort if a non icq contact is found - if (getContactUid(hContactsList[i], &contacts[i].uin, &szContactUid)) - break; // Abort if invalid contact - contacts[i].uid = contacts[i].uin ? nullptr : null_strdup(szContactUid); - contacts[i].szNick = NickFromHandle(hContactsList[i]); - // Compute this contact's length - nBodyLength += getUIDLen(contacts[i].uin, contacts[i].uid) + 1; - nBodyLength += mir_strlen(contacts[i].szNick) + 1; - } - - if (i == nContacts) { - debugLogA("Sending contacts to %d.", dwUin); - - // Compute count record's length - _itoa(nContacts, szCount, 10); - nBodyLength += mir_strlen(szCount) + 1; - - // Finally we need to copy the contact data into the packet body - char *pBody, *pBuffer = pBody = (char *)SAFE_MALLOC(nBodyLength); - null_strcpy(pBuffer, szCount, nBodyLength - 1); - pBuffer += mir_strlen(pBuffer); - *pBuffer++ = -2; - for (i = 0; i < nContacts; i++) { - if (contacts[i].uin) { - _itoa(contacts[i].uin, szContactUin, 10); - mir_strcpy(pBuffer, szContactUin); - } - else - mir_strcpy(pBuffer, contacts[i].uid); - pBuffer += mir_strlen(pBuffer); - *pBuffer++ = -2; - mir_strcpy(pBuffer, contacts[i].szNick); - pBuffer += mir_strlen(pBuffer); - *pBuffer++ = -2; - } - - for (i = 0; i < nContacts; i++) { // release memory - SAFE_FREE(&contacts[i].szNick); - SAFE_FREE(&contacts[i].uid); - } - - // Set up the ack type - cookie_message_data *pCookieData = CreateMessageCookieData(MTYPE_CONTACTS, hContact, dwUin, TRUE); - - if (m_bDCMsgEnabled && IsDirectConnectionOpen(hContact, DIRECTCONN_STANDARD, 0)) { - int iRes = icq_SendDirectMessage(hContact, pBody, nBodyLength, pCookieData, nullptr); - if (iRes) { - SAFE_FREE((void**)&pBody); - return iRes; // we succeded, return - } - } - - // Rate check - if (IsServerOverRate(ICQ_MSG_FAMILY, ICQ_MSG_SRV_SEND, RML_LIMIT)) { // rate is too high, the message will not go thru... - SAFE_FREE((void**)&pCookieData); - SAFE_FREE((void**)&pBody); - - return ReportGenericSendError(hContact, ACKTYPE_CONTACTS, "The message could not be delivered. You are sending too fast. Wait a while and try again."); - } - - // Select channel and send - WORD wPriority; - if (wRecipientStatus == ID_STATUS_ONLINE || wRecipientStatus == ID_STATUS_FREECHAT) - wPriority = 0x0001; - else - wPriority = 0x0021; - - dwCookie = icq_SendChannel2Message(dwUin, hContact, pBody, nBodyLength, wPriority, pCookieData, nullptr); - - // This will stop the message dialog from waiting for the real message delivery ack - if (pCookieData->nAckType == ACKTYPE_NONE) { - SendProtoAck(hContact, dwCookie, ACKRESULT_SUCCESS, ACKTYPE_CONTACTS, nullptr); - // We need to free this here since we will never see the real ack - // The actual cookie value will still have to be returned to the message dialog though - ReleaseCookie(dwCookie); - } - SAFE_FREE((void**)&pBody); - } - else dwCookie = ReportGenericSendError(hContact, ACKTYPE_CONTACTS, "Bad data (internal error #2)"); - } - } - else dwCookie = ReportGenericSendError(hContact, ACKTYPE_CONTACTS, "The reciever does not support receiving of contacts."); - } - return dwCookie; - } - - // Exit with Failure - return 0; -} - - -//////////////////////////////////////////////////////////////////////////////////////// -// SendFile - sends a file - -HANDLE CIcqProto::SendFile(MCONTACT hContact, const wchar_t* szDescription, wchar_t** ppszFiles) -{ - if (!icqOnline()) - return nullptr; - - if (hContact && szDescription && ppszFiles) { - DWORD dwUin; - uid_str szUid; - if (getContactUid(hContact, &dwUin, &szUid)) - return nullptr; // Invalid contact - - if (getContactStatus(hContact) != ID_STATUS_OFFLINE) { - if (CheckContactCapabilities(hContact, CAPF_OSCAR_FILE)) - return oftInitTransfer(hContact, dwUin, szUid, (LPCTSTR*)ppszFiles, szDescription); - - if (dwUin) { - WORD wClientVersion = getWord(hContact, "Version", 7); - - if (wClientVersion < 7) - debugLogA("IcqSendFile() can't send to version %u", wClientVersion); - else { - int i; - filetransfer* ft; - struct _stat statbuf; - - // Initialize filetransfer struct - ft = CreateFileTransfer(hContact, dwUin, (wClientVersion == 7) ? 7 : 8); - - for (ft->dwFileCount = 0; ppszFiles[ft->dwFileCount]; ft->dwFileCount++); - ft->pszFiles = (char **)SAFE_MALLOC(sizeof(char *)* ft->dwFileCount); - ft->dwTotalSize = 0; - for (i = 0; i < (int)ft->dwFileCount; i++) { - ft->pszFiles[i] = (ppszFiles[i]) ? make_utf8_string(ppszFiles[i]) : nullptr; - - if (_wstat(ppszFiles[i], &statbuf)) - debugLogA("IcqSendFile() was passed invalid filename(s)"); - else - ft->dwTotalSize += statbuf.st_size; - } - ft->szDescription = make_utf8_string(szDescription); - ft->dwTransferSpeed = 100; - ft->sending = 1; - ft->fileId = -1; - ft->iCurrentFile = 0; - ft->dwCookie = AllocateCookie(CKT_FILE, 0, hContact, ft); - ft->hConnection = nullptr; - - // Send file transfer request - debugLogA("Init file send"); - - char *pszFiles, szFiles[64]; - if (ft->dwFileCount == 1) { - pszFiles = strchr(ft->pszFiles[0], '\\'); - if (pszFiles) - pszFiles++; - else - pszFiles = ft->pszFiles[0]; - } - else { - char tmp[64]; - mir_snprintf(szFiles, ICQTranslateUtfStatic("%d Files", tmp, _countof(tmp)), ft->dwFileCount); - pszFiles = szFiles; - } - - // Send packet - if (ft->nVersion == 7) { - if (m_bDCMsgEnabled && IsDirectConnectionOpen(hContact, DIRECTCONN_STANDARD, 0)) { - int iRes = icq_sendFileSendDirectv7(ft, pszFiles); - if (iRes) return ft; // Success - } - debugLogA("Sending v%u file transfer request through server", 7); - icq_sendFileSendServv7(ft, pszFiles); - } - else { - if (m_bDCMsgEnabled && IsDirectConnectionOpen(hContact, DIRECTCONN_STANDARD, 0)) { - int iRes = icq_sendFileSendDirectv8(ft, pszFiles); - if (iRes) - return ft; // Success - } - debugLogA("Sending v%u file transfer request through server", 8); - icq_sendFileSendServv8(ft, pszFiles, ACKTYPE_NONE); - } - - return ft; // Success - } - } - } - } - - return nullptr; // Failure -} - - -//////////////////////////////////////////////////////////////////////////////////////// -// PS_SendMessage - sends a message - -int CIcqProto::SendMsg(MCONTACT hContact, int, const char* pszSrc) -{ - if (hContact == NULL || pszSrc == nullptr) - return NULL; - - DWORD dwCookie; - char* puszText = (char*)pszSrc; - int bNeedFreeU = 0; - - // Invalid contact - DWORD dwUin; - uid_str szUID; - if (getContactUid(hContact, &dwUin, &szUID)) - return ReportGenericSendError(hContact, ACKTYPE_MESSAGE, "The receiver has an invalid user ID."); - - WORD wRecipientStatus = getContactStatus(hContact); - - BOOL plain_ascii = IsUSASCII(puszText, mir_strlen(puszText)); - BOOL oldAnsi = plain_ascii || !CheckContactCapabilities(hContact, CAPF_UTF) || !getByte(hContact, "UnicodeSend", 1); - - if (m_bTempVisListEnabled && m_iStatus == ID_STATUS_INVISIBLE) - makeContactTemporaryVisible(hContact); // make us temporarily visible to contact - - // Failure scenarios - if (!icqOnline()) - dwCookie = ReportGenericSendError(hContact, ACKTYPE_MESSAGE, "You cannot send messages when you are offline."); - else if ((wRecipientStatus == ID_STATUS_OFFLINE) && (mir_strlen(puszText) > 4096)) - dwCookie = ReportGenericSendError(hContact, ACKTYPE_MESSAGE, "Messages to offline contacts must be shorter than 4096 characters."); - // Looks OK - else { - debugLogA("Send %smessage - Message cap is %u", puszText ? "unicode " : "", CheckContactCapabilities(hContact, CAPF_SRV_RELAY)); - debugLogA("Send %smessage - Contact status is %u", puszText ? "unicode " : "", wRecipientStatus); - - if (dwUin && m_bDCMsgEnabled && IsDirectConnectionOpen(hContact, DIRECTCONN_STANDARD, 0)) { // send thru direct - char *dc_msg = puszText; - char *dc_cap = plain_ascii ? NULL : CAP_UTF8MSGS; - char *szUserAnsi = nullptr; - - if (!plain_ascii && oldAnsi) { - szUserAnsi = ConvertMsgToUserSpecificAnsi(hContact, puszText); - if (szUserAnsi) { - dc_msg = szUserAnsi; - dc_cap = NULL; - } - } - - // Set up the ack type - cookie_message_data *pCookieData = CreateMessageCookieData(MTYPE_PLAIN, hContact, dwUin, TRUE); - pCookieData->nAckType = ACKTYPE_CLIENT; - dwCookie = icq_SendDirectMessage(hContact, dc_msg, mir_strlen(dc_msg), pCookieData, dc_cap); - - SAFE_FREE(&szUserAnsi); - if (dwCookie) // free the buffers if alloced - return dwCookie; // we succeded, return - - // on failure, fallback to send thru server - } - - /// TODO: add support for RTL & user customizable font - { - char *mng = MangleXml(puszText, mir_strlen(puszText)); - size_t len = mir_strlen(mng); - mng = (char*)SAFE_REALLOC(mng, len + 28); - memmove(mng + 12, mng, len + 1); - memcpy(mng, "", 12); - mir_strcat(mng, ""); - puszText = mng; - bNeedFreeU = 1; - } - - WCHAR *pwszText = plain_ascii ? nullptr : make_unicode_string(puszText); - if ((plain_ascii ? mir_strlen(puszText) : mir_wstrlen(pwszText) * sizeof(WCHAR)) > MAX_MESSAGESNACSIZE) { // max length check // TLV(2) is currently limited to 0xA00 bytes in online mode - // only limit to not get disconnected, all other will be handled by error 0x0A - dwCookie = ReportGenericSendError(hContact, ACKTYPE_MESSAGE, "The message could not be delivered, it is too long."); - - // free the buffers if alloced - SAFE_FREE((void**)&pwszText); - if (bNeedFreeU) SAFE_FREE(&puszText); - - return dwCookie; - } - // Rate check - if (IsServerOverRate(ICQ_MSG_FAMILY, ICQ_MSG_SRV_SEND, RML_LIMIT)) { // rate is too high, the message will not go thru... - dwCookie = ReportGenericSendError(hContact, ACKTYPE_MESSAGE, "The message could not be delivered. You are sending too fast. Wait a while and try again."); - - // free the buffers if alloced - SAFE_FREE((void**)&pwszText); - if (bNeedFreeU) SAFE_FREE(&puszText); - - return dwCookie; - } - - cookie_message_data *pCookieData = CreateMessageCookieData(MTYPE_PLAIN, hContact, dwUin, FALSE); - - if (plain_ascii) - dwCookie = icq_SendChannel1Message(dwUin, szUID, hContact, puszText, pCookieData); - else - dwCookie = icq_SendChannel1MessageW(dwUin, szUID, hContact, pwszText, pCookieData); - // free the unicode message - SAFE_FREE((void**)&pwszText); - - // This will stop the message dialog from waiting for the real message delivery ack - if (pCookieData && pCookieData->nAckType == ACKTYPE_NONE) { - SendProtoAck(hContact, dwCookie, ACKRESULT_SUCCESS, ACKTYPE_MESSAGE, nullptr); - // We need to free this here since we will never see the real ack - // The actual cookie value will still have to be returned to the message dialog though - ReleaseCookie(dwCookie); - } - } - // free the buffers if alloced - if (bNeedFreeU) SAFE_FREE(&puszText); - - return dwCookie; // Success -} - - -//////////////////////////////////////////////////////////////////////////////////////// -// SendUrl - -int CIcqProto::SendUrl(MCONTACT hContact, int, const char* url) -{ - if (hContact == NULL || url == nullptr) - return 0; - - DWORD dwUin; - if (getContactUid(hContact, &dwUin, nullptr)) // Invalid contact - return ReportGenericSendError(hContact, ACKTYPE_URL, "The receiver has an invalid user ID."); - - WORD wRecipientStatus = getContactStatus(hContact); - - // Failure - if (!icqOnline()) { - ReportGenericSendError(hContact, ACKTYPE_URL, "You cannot send messages when you are offline."); - return 0; - } - - // Set up the ack type - cookie_message_data *pCookieData = CreateMessageCookieData(MTYPE_URL, hContact, dwUin, TRUE); - - // Format the body - size_t nUrlLen = mir_strlen(url); - char *szDesc = (char *)url + nUrlLen + 1; - size_t nDescLen = mir_strlen(szDesc); - size_t nBodyLen = nUrlLen + nDescLen + 2; - char *szBody = (char *)_alloca(nBodyLen); - mir_strcpy(szBody, szDesc); - szBody[nDescLen] = -2; // Separator - mir_strcpy(szBody + nDescLen + 1, url); - - if (m_bDCMsgEnabled && IsDirectConnectionOpen(hContact, DIRECTCONN_STANDARD, 0)) { - int iRes = icq_SendDirectMessage(hContact, szBody, nBodyLen, pCookieData, nullptr); - if (iRes) - return iRes; // we succeded, return - } - - // Rate check - if (IsServerOverRate(ICQ_MSG_FAMILY, ICQ_MSG_SRV_SEND, RML_LIMIT)) { // rate is too high, the message will not go thru... - SAFE_FREE((void**)&pCookieData); - return ReportGenericSendError(hContact, ACKTYPE_URL, "The message could not be delivered. You are sending too fast. Wait a while and try again."); - } - - // Select channel and send - WORD wPriority; - if (wRecipientStatus == ID_STATUS_ONLINE || wRecipientStatus == ID_STATUS_FREECHAT) - wPriority = 0x0001; - else - wPriority = 0x0021; - - DWORD dwCookie = icq_SendChannel2Message(dwUin, hContact, szBody, nBodyLen, wPriority, pCookieData, nullptr); - - // This will stop the message dialog from waiting for the real message delivery ack - if (pCookieData->nAckType == ACKTYPE_NONE) { - SendProtoAck(hContact, dwCookie, ACKRESULT_SUCCESS, ACKTYPE_URL, nullptr); - // We need to free this here since we will never see the real ack - // The actual cookie value will still have to be returned to the message dialog though - ReleaseCookie(dwCookie); - } - - return dwCookie; // Success -} - -//////////////////////////////////////////////////////////////////////////////////////// -// PS_SetApparentMode - sets the visibility status - -int CIcqProto::SetApparentMode(MCONTACT hContact, int mode) -{ - DWORD uin; - uid_str uid; - if (getContactUid(hContact, &uin, &uid)) - return 1; // Invalid contact - - if (hContact) { - // Only 3 modes are supported - if (mode == 0 || mode == ID_STATUS_ONLINE || mode == ID_STATUS_OFFLINE) { - int oldMode = getWord(hContact, "ApparentMode", 0); - - // Don't send redundant updates - if (mode != oldMode) { - setWord(hContact, "ApparentMode", WORD(mode)); - - // Not being online is only an error when in SS mode. This is not handled - // yet so we just ignore this for now. - if (icqOnline()) { - if (oldMode != 0) { // Remove from old list - if (oldMode == ID_STATUS_OFFLINE && getWord(hContact, DBSETTING_SERVLIST_IGNORE, 0)) { // Need to remove Ignore item as well - icq_removeServerPrivacyItem(hContact, uin, uid, getWord(hContact, DBSETTING_SERVLIST_IGNORE, 0), SSI_ITEM_IGNORE); - - setWord(hContact, DBSETTING_SERVLIST_IGNORE, 0); - } - icq_sendChangeVisInvis(hContact, uin, uid, oldMode == ID_STATUS_OFFLINE, 0); - } - if (mode != 0) { // Add to new list - if (mode == ID_STATUS_OFFLINE && getWord(hContact, DBSETTING_SERVLIST_IGNORE, 0)) - return 0; // Success: offline by ignore item - - icq_sendChangeVisInvis(hContact, uin, uid, mode == ID_STATUS_OFFLINE, 1); - } - } - - return 0; // Success - } - } - } - - return 1; // Failure -} - - -//////////////////////////////////////////////////////////////////////////////////////// -// PrepareStatusNote - returns correct status note for given status - -char* CIcqProto::PrepareStatusNote(int nStatus) -{ - char *szStatusNote = nullptr; - BYTE bXStatus = getContactXStatus(NULL); - - // use custom status message as status note - if (bXStatus) - szStatusNote = getSettingStringUtf(NULL, DBSETTING_XSTATUS_MSG, nullptr); - - // get standard status message (no custom status defined) - if (szStatusNote == nullptr) { - mir_cslock l(m_modeMsgsMutex); - - char **pszStatusNote = MirandaStatusToAwayMsg(nStatus); - if (pszStatusNote) - szStatusNote = null_strdup(*pszStatusNote); - } - - if (szStatusNote == nullptr) // nothing available. set empty status note - szStatusNote = null_strdup(""); - - return szStatusNote; -} - - -//////////////////////////////////////////////////////////////////////////////////////// -// PS_SetStatus - sets the protocol status - -int CIcqProto::SetStatus(int iNewStatus) -{ - int nNewStatus = MirandaStatusToSupported(iNewStatus); - - // check if netlib handles are ready - if (!m_hNetlibUser) - return 0; - - if (m_bTempVisListEnabled && icqOnline()) // remove temporary visible users - sendEntireListServ(ICQ_BOS_FAMILY, ICQ_CLI_REMOVETEMPVISIBLE, BUL_TEMPVISIBLE); - - if (nNewStatus == m_iStatus) - return 0; - - // clear custom status on status change - if (getByte("XStatusReset", DEFAULT_XSTATUS_RESET)) - setXStatusEx(0, 0); - - // New status is OFFLINE - if (nNewStatus == ID_STATUS_OFFLINE) { // for quick logoff - if (icqOnline()) { // set offline status note (otherwise the old will remain) - char *szOfflineNote = PrepareStatusNote(nNewStatus); - SetStatusNote(szOfflineNote, 0, FALSE); - SAFE_FREE(&szOfflineNote); - } - - m_iDesiredStatus = nNewStatus; - - if (hServerConn) { // Connected, Send disconnect packet - icq_sendCloseConnection(); - icq_serverDisconnect(); - - m_bConnectionLost = false; - debugLogA("Logged off."); - } - } - else { - switch (m_iStatus) { - - // We are offline and need to connect - case ID_STATUS_OFFLINE: - // Update user connection settings - UpdateGlobalSettings(); - - // Read UIN from database - m_dwLocalUIN = getContactUin(NULL); - if (m_dwLocalUIN == 0) { - SetCurrentStatus(ID_STATUS_OFFLINE); - ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, nullptr, LOGINERR_BADUSERID); - icq_LogMessage(LOG_FATAL, LPGEN("You have not entered an ICQ number.\nConfigure this in Options -> Network -> ICQ and try again.")); - return 0; - } - - // Set status to 'Connecting' - m_iDesiredStatus = nNewStatus; - SetCurrentStatus(ID_STATUS_CONNECTING); - - // Read password from database - { - char *pszPwd = GetUserPassword(FALSE); - if (pszPwd) - icq_login(pszPwd); - else - RequestPassword(); - } - break; - - // We are connecting... We only need to change the going online status - case ID_STATUS_CONNECTING: - m_iDesiredStatus = nNewStatus; - break; - - // We are already connected so we should just change status - default: - SetCurrentStatus(nNewStatus); - - char *szStatusNote = PrepareStatusNote(nNewStatus); - - //! This is a bit tricky, we do trigger status note change thread and then - // change the status note right away (this spares one packet) - so SetStatusNote() - // will only change User Details Directory - SetStatusNote(szStatusNote, 6000, FALSE); - - if (m_iStatus == ID_STATUS_INVISIBLE) { - if (m_bSsiEnabled) - updateServVisibilityCode(3); - icq_setstatus(MirandaStatusToIcq(m_iStatus), szStatusNote); - } - else { - icq_setstatus(MirandaStatusToIcq(m_iStatus), szStatusNote); - if (m_bSsiEnabled) - updateServVisibilityCode(4); - } - SAFE_FREE(&szStatusNote); - - mir_cslock l(m_modeMsgsMutex); - char ** pszStatusNote = MirandaStatusToAwayMsg(m_iStatus); - if (pszStatusNote) - icq_sendSetAimAwayMsgServ(*pszStatusNote); - else // clear the away message - icq_sendSetAimAwayMsgServ(nullptr); - } - } - - return 0; -} - -//////////////////////////////////////////////////////////////////////////////////////// -// GetAwayMsgThread - return a contact's status message - -struct status_message_thread_data -{ - MCONTACT hContact; - char *szMessage; - HANDLE hProcess; -}; - -void __cdecl CIcqProto::GetAwayMsgThread(void *pStatusData) -{ - Thread_SetName("ICQ: GetAwayMsgThread"); - - status_message_thread_data *pThreadData = (status_message_thread_data*)pStatusData; - if (pThreadData) { - // wait a little - Sleep(100); - - setStatusMsgVar(pThreadData->hContact, pThreadData->szMessage, false); - - wchar_t *tszMsg = mir_utf8decodeW(pThreadData->szMessage); - ProtoBroadcastAck(pThreadData->hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, pThreadData->hProcess, (LPARAM)tszMsg); - mir_free(tszMsg); - - SAFE_FREE(&pThreadData->szMessage); - SAFE_FREE((void**)&pThreadData); - } -} - -//////////////////////////////////////////////////////////////////////////////////////// -// PS_GetAwayMsg - returns a contact's away message - -HANDLE CIcqProto::GetAwayMsg(MCONTACT hContact) -{ - DWORD dwUin; - uid_str szUID; - if (getContactUid(hContact, &dwUin, &szUID)) - return nullptr; // Invalid contact - - if (!dwUin || !CheckContactCapabilities(hContact, CAPF_STATUS_MESSAGES)) { // No individual status messages, check if the contact has Status Note, if yes give it - char *szStatusNote = getSettingStringUtf(hContact, DBSETTING_STATUS_NOTE, nullptr); - - if (mir_strlen(szStatusNote) > 0) { // Give Status Note - status_message_thread_data *pThreadData = (status_message_thread_data*)SAFE_MALLOC(sizeof(status_message_thread_data)); - - pThreadData->hContact = hContact; - pThreadData->szMessage = szStatusNote; - pThreadData->hProcess = (HANDLE)GenerateCookie(0); - ForkThread(&CIcqProto::GetAwayMsgThread, pThreadData); - - return pThreadData->hProcess; - } - SAFE_FREE(&szStatusNote); - } - - if (!icqOnline()) - return nullptr; - - WORD wStatus = getContactStatus(hContact); - - if (dwUin) { - int wMessageType = 0; - - switch (wStatus) { - case ID_STATUS_ONLINE: - if (CheckContactCapabilities(hContact, CAPF_STATUS_MESSAGES)) - wMessageType = MTYPE_AUTOONLINE; - break; - - case ID_STATUS_AWAY: - wMessageType = MTYPE_AUTOAWAY; - break; - - case ID_STATUS_NA: - wMessageType = MTYPE_AUTONA; - break; - - case ID_STATUS_OCCUPIED: - wMessageType = MTYPE_AUTOBUSY; - break; - - case ID_STATUS_DND: - wMessageType = MTYPE_AUTODND; - break; - - case ID_STATUS_FREECHAT: - wMessageType = MTYPE_AUTOFFC; - break; - } - - if (wMessageType) { - if (m_bDCMsgEnabled && IsDirectConnectionOpen(hContact, DIRECTCONN_STANDARD, 0)) { - int iRes = icq_sendGetAwayMsgDirect(hContact, wMessageType); - if (iRes) return (HANDLE)iRes; // we succeded, return - } - - WORD wVer = getWord(hContact, "Version", 0) <= 8 ? 8 : ICQ_VERSION; - if (CheckContactCapabilities(hContact, CAPF_STATUS_MESSAGES)) - return (HANDLE)icq_sendGetAwayMsgServExt(hContact, dwUin, szUID, wMessageType, wVer); - - return (HANDLE)icq_sendGetAwayMsgServ(hContact, dwUin, wMessageType, wVer); - } - } - else { // AIM contact - if (wStatus == ID_STATUS_AWAY) - return (HANDLE)icq_sendGetAimAwayMsgServ(hContact, szUID, MTYPE_AUTOAWAY); - } - - return nullptr; // Failure -} - - -//////////////////////////////////////////////////////////////////////////////////////// -// PSR_AWAYMSG - processes received status mode message - -int CIcqProto::RecvAwayMsg(MCONTACT hContact, int, PROTORECVEVENT* evt) -{ - setStatusMsgVar(hContact, evt->szMessage, false); - - wchar_t* pszMsg = mir_utf8decodeW(evt->szMessage); - ProtoBroadcastAck(hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, (HANDLE)evt->lParam, (LPARAM)pszMsg); - mir_free(pszMsg); - return 0; -} - - -//////////////////////////////////////////////////////////////////////////////////////// -// PS_SetAwayMsg - sets the away status message - -int CIcqProto::SetAwayMsg(int status, const wchar_t* msg) -{ - mir_cslock l(m_modeMsgsMutex); - - char **ppszMsg = MirandaStatusToAwayMsg(MirandaStatusToSupported(status)); - if (!ppszMsg) - return 1; // Failure - - // Prepare UTF-8 status message - char *szNewUtf = make_utf8_string(msg); - - if (mir_strcmp(szNewUtf, *ppszMsg)) { - // Free old message - SAFE_FREE(ppszMsg); - - // Set new message - *ppszMsg = szNewUtf; - szNewUtf = nullptr; - - if ((m_iStatus == status) && icqOnline()) { // update current status note - char *szNote = *ppszMsg ? *ppszMsg : ""; - - BYTE bXStatus = getContactXStatus(NULL); - if (!bXStatus) - SetStatusNote(szNote, 1000, FALSE); - - icq_sendSetAimAwayMsgServ(*ppszMsg); - } - } - SAFE_FREE(&szNewUtf); - - return 0; // Success -} - - -///////////////////////////////////////////////////////////////////////////////////////// -// GetMyAwayMsg - obtain the current away message - -INT_PTR CIcqProto::GetMyAwayMsg(WPARAM wParam, LPARAM lParam) -{ - mir_cslock l(m_modeMsgsMutex); - - char **ppszMsg = MirandaStatusToAwayMsg(wParam ? wParam : m_iStatus); - - if (!ppszMsg || !*ppszMsg) - return 0; - - size_t nMsgLen = mir_strlen(*ppszMsg) + 1; - - if (lParam & SGMA_UNICODE) { - WCHAR *szMsg = (WCHAR*)_alloca(nMsgLen * sizeof(WCHAR)); - - make_unicode_string_static(*ppszMsg, szMsg, nMsgLen); - return (INT_PTR)mir_wstrdup(szMsg); - } - else { // convert to ansi - char *szMsg = (char*)_alloca(nMsgLen); - - if (utf8_decode_static(*ppszMsg, szMsg, nMsgLen)) - return (INT_PTR)mir_strdup(szMsg); - } - - return 0; -} - - -///////////////////////////////////////////////////////////////////////////////////////// -// PS_UserIsTyping - sends a UTN notification - -int CIcqProto::UserIsTyping(MCONTACT hContact, int type) -{ - if (hContact && icqOnline()) { - if (CheckContactCapabilities(hContact, CAPF_TYPING)) { - switch (type) { - case PROTOTYPE_SELFTYPING_ON: - sendTypingNotification(hContact, MTN_BEGUN); - return 0; - - case PROTOTYPE_SELFTYPING_OFF: - sendTypingNotification(hContact, MTN_FINISHED); - return 0; - } - } - } - - return 1; -} - - -///////////////////////////////////////////////////////////////////////////////////////// -// OnEvent - maintain protocol events - -void CIcqProto::OnErase() -{ - char szDbSetting[MAX_PATH]; - mir_snprintf(szDbSetting, "%sP2P", m_szModuleName); - db_delete_module(0, szDbSetting); - mir_snprintf(szDbSetting, "%sSrvGroups", m_szModuleName); - db_delete_module(0, szDbSetting); - mir_snprintf(szDbSetting, "%sGroups", m_szModuleName); - db_delete_module(0, szDbSetting); -} diff --git a/protocols/IcqOscarJ/src/icq_proto.h b/protocols/IcqOscarJ/src/icq_proto.h deleted file mode 100644 index f50c445126..0000000000 --- a/protocols/IcqOscarJ/src/icq_proto.h +++ /dev/null @@ -1,902 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera, George Hazan -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// Protocol Interface declarations -// ----------------------------------------------------------------------------- - -#ifndef _ICQ_PROTO_H_ -#define _ICQ_PROTO_H_ - -#include "m_system.h" -#include "m_protoint.h" - -#define LISTSIZE 100 - -#define XSTATUS_COUNT 86 - -// for InfoUpdate -struct userinfo -{ - DWORD dwUin; - MCONTACT hContact; - time_t queued; -}; - -struct CIcqProto : public PROTO -{ - CIcqProto(const char*, const wchar_t*); - ~CIcqProto(); - - //==================================================================================== - // PROTO_INTERFACE - //==================================================================================== - - MCONTACT AddToList( int flags, PROTOSEARCHRESULT *psr) override; - MCONTACT AddToListByEvent( int flags, int iContact, MEVENT hDbEvent) override; - - int Authorize(MEVENT hDbEvent) override; - int AuthDeny(MEVENT hDbEvent, const wchar_t *szReason) override; - int AuthRecv(MCONTACT hContact, PROTORECVEVENT*) override; - int AuthRequest(MCONTACT hContact, const wchar_t *szMessage) override; - - HANDLE FileAllow(MCONTACT hContact, HANDLE hTransfer, const wchar_t *szPath) override; - int FileCancel(MCONTACT hContact, HANDLE hTransfer) override; - int FileDeny(MCONTACT hContact, HANDLE hTransfer, const wchar_t *szReason) override; - int FileResume( HANDLE hTransfer, int *action, const wchar_t **szFilename) override; - - INT_PTR GetCaps(int type, MCONTACT hContact = NULL) override; - int GetInfo(MCONTACT hContact, int infoType) override; - - HANDLE SearchBasic(const wchar_t *id) override; - HANDLE SearchByEmail(const wchar_t *email) override; - HANDLE SearchByName(const wchar_t *nick, const wchar_t *firstName, const wchar_t *lastName) override; - HWND SearchAdvanced(HWND owner) override; - HWND CreateExtendedSearchUI(HWND owner) override; - - int RecvContacts(MCONTACT hContact, PROTORECVEVENT*) override; - MEVENT RecvMsg(MCONTACT hContact, PROTORECVEVENT*) override; - - int SendContacts(MCONTACT hContact, int flags, int nContacts, MCONTACT *hContactsList) override; - HANDLE SendFile(MCONTACT hContact, const wchar_t *szDescription, wchar_t **ppszFiles) override; - int SendMsg(MCONTACT hContact, int flags, const char *msg) override; - int SendUrl(MCONTACT hContact, int flags, const char *url) override; - - int SetApparentMode(MCONTACT hContact, int mode) override; - int SetStatus(int iNewStatus) override; - - HANDLE GetAwayMsg(MCONTACT hContact) override; - int RecvAwayMsg(MCONTACT hContact, int mode, PROTORECVEVENT *evt) override; - int SetAwayMsg(int m_iStatus, const wchar_t *msg) override; - - int UserIsTyping(MCONTACT hContact, int type) override; - - void OnContactDeleted(MCONTACT) override; - void OnErase() override; - void OnModulesLoaded() override; - void OnShutdown() override; - - //====| Services |==================================================================== - INT_PTR __cdecl AddServerContact(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl GetInfoSetting(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl ChangeInfoEx(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl GetAvatarCaps(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl GetAvatarInfo(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl GetMyAvatar(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl GetMyAwayMsg(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl GetXStatusEx(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl GetXStatusIcon(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl GrantAuthorization(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl menuXStatus(WPARAM wParam,LPARAM lParam,LPARAM fParam); - INT_PTR __cdecl OpenWebProfile(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl RequestAdvStatusIconIdx(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl RequestAuthorization(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl RequestXStatusDetails(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl RevokeAuthorization(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl SendSms(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl SendYouWereAdded(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl SetMyAvatar(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl SetNickName(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl SetXStatusEx(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl ShowXStatusDetails(WPARAM wParam, LPARAM lParam); - - INT_PTR __cdecl OnCreateAccMgrUI(WPARAM, LPARAM); - - //====| Events |====================================================================== - int __cdecl OnIdleChanged(WPARAM, LPARAM); - int __cdecl OnOptionsInit(WPARAM, LPARAM); - int __cdecl OnPreBuildContactMenu(WPARAM, LPARAM); - int __cdecl OnUserInfoInit(WPARAM, LPARAM); - - int __cdecl OnPreBuildStatusMenu(WPARAM, LPARAM); - - //====| Data |======================================================================== - HNETLIBUSER m_hDirectNetlibUser; - - BYTE m_bGatewayMode; - BYTE m_bSecureLogin; - BYTE m_bSecureConnection; - BYTE m_bLegacyFix; - WORD m_wAnsiCodepage; - BYTE m_bDCMsgEnabled; - BYTE m_bTempVisListEnabled; - BYTE m_bSsiEnabled; - BYTE m_bSsiSimpleGroups; - BYTE m_bAvatarsEnabled; - BYTE m_bXStatusEnabled; - BYTE m_bMoodsEnabled; - - mir_cs localSeqMutex; - mir_cs connectionHandleMutex; - - bool m_bIdleMode; - DWORD m_dwLocalUIN; - BYTE m_bConnectionLost; - - char m_szPassword[PASSWORDMAXLEN+1]; - BYTE m_bRememberPwd; - - int cheekySearchId; - DWORD cheekySearchUin; - char* cheekySearchUid; - - /******************************************************************* - * Function declarations - *******************************************************************/ - - //----| capabilities.cpp |------------------------------------------------------------ - // Deletes all oscar capabilities for a given contact. - void ClearAllContactCapabilities(MCONTACT hContact); - - // Deletes one or many oscar capabilities for a given contact. - void ClearContactCapabilities(MCONTACT hContact, DWORD fdwCapabilities); - - // Sets one or many oscar capabilities for a given contact. - void SetContactCapabilities(MCONTACT hContact, DWORD fdwCapabilities); - - // Returns true if the given contact supports the requested capabilites. - BOOL CheckContactCapabilities(MCONTACT hContact, DWORD fdwCapabilities); - - // Scans a binary buffer for oscar capabilities and adds them to the contact. - void AddCapabilitiesFromBuffer(MCONTACT hContact, BYTE *pBuffer, int nLength); - - // Scans a binary buffer for oscar capabilities and sets them to the contact. - void SetCapabilitiesFromBuffer(MCONTACT hContact, BYTE *pBuffer, int nLength, BOOL bReset); - - //----| chan_01login.cpp |------------------------------------------------------------ - void handleLoginChannel(BYTE *buf, size_t datalen, serverthread_info *info); - - //----| chan_02data.cpp |------------------------------------------------------------- - void handleDataChannel(BYTE *buf, size_t wLen, serverthread_info *info); - - void LogFamilyError(WORD wFamily, WORD wError); - - //----| chan_03error.cpp |------------------------------------------------------------ - void handleErrorChannel(unsigned char *buf, size_t datalen); - - //----| chan_04close.cpp |------------------------------------------------------------ - void handleCloseChannel(BYTE *buf, size_t datalen, serverthread_info *info); - void handleLoginReply(BYTE *buf, size_t datalen, serverthread_info *info); - void handleMigration(serverthread_info *info); - void handleSignonError(WORD wError); - - int connectNewServer(serverthread_info *info); - - //----| chan_05ping.cpp |------------------------------------------------------------- - void handlePingChannel(BYTE *buf, size_t wLen); - - void StartKeepAlive(serverthread_info *info); - void StopKeepAlive(serverthread_info *info); - void CheckKeepAlive(serverthread_info *info); - - //----| cookies.cpp |----------------------------------------------------------------- - mir_cs cookieMutex; // we want this in avatar thread, used as queue lock - OBJLIST cookies; - WORD wCookieSeq; - - DWORD AllocateCookie(BYTE bType, WORD wIdent, MCONTACT hContact, void *pvExtra); - void FreeCookie(DWORD dwCookie); - void FreeCookieByData(BYTE bType, void *pvExtra); - void ReleaseCookie(DWORD dwCookie); - DWORD GenerateCookie(WORD wIdent); - - int GetCookieType(DWORD dwCookie); - - int FindCookie(DWORD wCookie, MCONTACT *phContact, void **ppvExtra); - int FindCookieByData(void *pvExtra, DWORD *pdwCookie, MCONTACT *phContact); - int FindCookieByType(BYTE bType, DWORD *pdwCookie, MCONTACT *phContact, void **ppvExtra); - int FindMessageCookie(DWORD dwMsgID1, DWORD dwMsgID2, DWORD *pdwCookie, MCONTACT *phContact, cookie_message_data **ppvExtra); - - void InitMessageCookie(cookie_message_data *pCookie); - cookie_message_data* CreateMessageCookie(WORD bMsgType, BYTE bAckType); - cookie_message_data* CreateMessageCookieData(BYTE bMsgType, MCONTACT hContact, DWORD dwUin, int bUseSrvRelay); - - void RemoveExpiredCookies(void); - - //----| directpackets.cpp |----------------------------------------------------------- - void icq_sendDirectMsgAck(directconnect* dc, WORD wCookie, BYTE bMsgType, BYTE bMsgFlags, char* szCap); - DWORD icq_sendGetAwayMsgDirect(MCONTACT hContact, int type); - void icq_sendAwayMsgReplyDirect(directconnect *dc, WORD wCookie, BYTE msgType, const char** szMsg); - void icq_sendFileAcceptDirect(MCONTACT hContact, filetransfer *ft); - void icq_sendFileDenyDirect(MCONTACT hContact, filetransfer *ft, const char *szReason); - int icq_sendFileSendDirectv7(filetransfer *ft, const char *pszFiles); - int icq_sendFileSendDirectv8(filetransfer *ft, const char *pszFiles); - DWORD icq_SendDirectMessage(MCONTACT hContact, const char *szMessage, size_t nBodyLength, cookie_message_data *pCookieData, char *szCap); - void icq_sendXtrazRequestDirect(MCONTACT hContact, DWORD dwCookie, char* szBody, size_t nBodyLen, WORD wType); - void icq_sendXtrazResponseDirect(MCONTACT hContact, WORD wCookie, char* szBody, size_t nBodyLen, WORD wType); - - //----| fam_01service.cpp |----------------------------------------------------------- - void handleServiceFam(BYTE *pBuffer, size_t wBufferLength, snac_header *pSnacHeader, serverthread_info *info); - char* buildUinList(int subtype, size_t wMaxLen, MCONTACT *hContactResume); - void sendEntireListServ(WORD wFamily, WORD wSubtype, int listType); - void setUserInfo(void); - void handleServUINSettings(int nPort, serverthread_info *info); - - //----| fam_02location.cpp |---------------------------------------------------------- - void handleLocationFam(BYTE *pBuffer, size_t wBufferLength, snac_header *pSnacHeader); - void handleLocationUserInfoReply(BYTE* buf, size_t wLen, DWORD dwCookie); - - //----| fam_03buddy.cpp |------------------------------------------------------------- - void handleBuddyFam(BYTE *pBuffer, size_t wBufferLength, snac_header *pSnacHeader, serverthread_info *info); - void handleReplyBuddy(BYTE *buf, size_t wPackLen); - void handleUserOffline(BYTE *buf, size_t wPackLen); - void handleUserOnline(BYTE *buf, size_t wPackLen, serverthread_info *info); - void parseStatusNote(DWORD dwUin, char *szUid, MCONTACT hContact, oscar_tlv_chain *pChain); - void handleNotifyRejected(BYTE *buf, size_t wPackLen); - - //----| fam_04message.cpp |----------------------------------------------------------- - icq_mode_messages m_modeMsgs; - mir_cs m_modeMsgsMutex; - HANDLE m_modeMsgsEvent; - - void handleMsgFam(BYTE *pBuffer, size_t wBufferLength, snac_header *pSnacHeader); - - void handleReplyICBM(); - void handleRecvServMsg(BYTE *buf, size_t wLen, DWORD dwRef); - void handleRecvServMsgType1(BYTE *buf, size_t wLen, DWORD dwUin, char *szUID, DWORD dwMsgID1, DWORD dwRef); - void handleRecvServMsgType2(BYTE *buf, size_t wLen, DWORD dwUin, char *szUID, DWORD dwMsgID1, DWORD dwMsgID2); - void handleRecvServMsgType4(BYTE *buf, size_t wLen, DWORD dwUin, char *szUID, DWORD dwMsgID1, DWORD dwMsgID2, DWORD dwRef); - void handleRecvServMsgError(BYTE *buf, size_t wLen, DWORD dwRef); - void handleRecvMsgResponse(BYTE *buf, size_t wLen); - void handleServerAck(BYTE *buf, size_t wLen, DWORD dwRef); - void handleStatusMsgReply(const char *szPrefix, MCONTACT hContact, DWORD dwUin, int bMsgType, WORD wCookie, const char *szMsg); - void handleTypingNotification(BYTE *buf, size_t wLen); - void handleMissedMsg(BYTE *buf, size_t wLen); - void handleOffineMessagesReply(DWORD dwRef); - void handleRecvServMsgContacts(BYTE *buf, size_t wLen, DWORD dwUin, char *szUID, DWORD dwID1, DWORD dwID2, WORD wCommand); - void handleRuntimeError(WORD wError); - - void parseServRelayData(BYTE *pDataBuf, size_t wLen, MCONTACT hContact, DWORD dwUin, char *szUID, DWORD dwMsgID1, DWORD dwMsgID2, WORD wAckType); - void parseServRelayPluginData(BYTE *pDataBuf, size_t wLen, DWORD dwUin, char *szUID, DWORD dwMsgID1, DWORD dwMsgID2, WORD wAckType, BYTE bFlags, WORD wStatus, WORD wCookie, WORD wVersion); - - HANDLE handleMessageAck(DWORD dwUin, char *szUID, WORD wCookie, int type, PBYTE buf, BYTE bFlags); - void handleMessageTypes(DWORD dwUin, char *szUID, DWORD dwTimestamp, DWORD dwMsgID, DWORD dwMsgID2, WORD wCookie, WORD wVersion, int type, int flags, WORD wAckType, size_t dwDataLen, size_t wMsgLen, char *pMsg, int nMsgFlags, message_ack_params *pAckParams); - void sendMessageTypesAck(MCONTACT hContact, int bUnicode, message_ack_params *pArgs); - void sendTypingNotification(MCONTACT hContact, WORD wMTNCode); - - int unpackPluginTypeId(BYTE **pBuffer, size_t *pwLen, int *pTypeId, WORD *pFunctionId, BOOL bThruDC); - - char* convertMsgToUserSpecificUtf(MCONTACT hContact, const char *szMsg); - - //----| fam_09bos.cpp |--------------------------------------------------------------- - void handleBosFam(unsigned char *pBuffer, size_t wBufferLength, snac_header* pSnacHeader); - void handlePrivacyRightsReply(unsigned char *pBuffer, size_t wBufferLength); - void makeContactTemporaryVisible(MCONTACT hContact); - - //----| fam_0alookup.cpp |------------------------------------------------------------ - void handleLookupFam(unsigned char *pBuffer, size_t wBufferLength, snac_header* pSnacHeader); - - void handleLookupEmailReply(BYTE* buf, size_t wLen, DWORD dwCookie); - void ReleaseLookupCookie(DWORD dwCookie, cookie_search *pCookie); - - //----| fam_0bstatus.cpp |------------------------------------------------------------ - void handleStatusFam(unsigned char *pBuffer, size_t wBufferLength, snac_header* pSnacHeader); - - //----| fam_13servclist.cpp |--------------------------------------------------------- - BOOL bIsSyncingCL; - - WORD m_wServerListLimits[0x20]; - WORD m_wServerListGroupMaxContacts; - WORD m_wServerListRecordNameMaxLength; - - void handleServCListFam(BYTE *pBuffer, size_t wBufferLength, snac_header* pSnacHeader, serverthread_info *info); - void handleServerCListRightsReply(BYTE *buf, size_t wLen); - void handleServerCListAck(cookie_servlist_action* sc, WORD wError); - void handleServerCListReply(BYTE *buf, size_t wLen, WORD wFlags, serverthread_info *info); - void handleServerCListItemAdd(WORD wItemId, WORD wItemType, oscar_tlv_chain *pItemData); - void handleServerCListItemUpdate(const char *szRecordName, WORD wItemType, oscar_tlv_chain *pItemData); - void handleServerCListItemDelete(const char *szRecordName, WORD wItemId, WORD wItemType); - void handleRecvAuthRequest(BYTE *buf, size_t wLen); - void handleRecvAuthResponse(BYTE *buf, size_t wLen); - void handleRecvAdded(BYTE *buf, size_t wLen); - - MCONTACT HContactFromRecordName(const char *szRecordName, int *bAdded); - - void icq_sendServerBeginOperation(int bImport); - void icq_sendServerEndOperation(); - void sendRosterAck(void); - - int getServerDataFromItemTLV(oscar_tlv_chain* pChain, unsigned char *buf); - DWORD updateServerGroupData(WORD wGroupId, void *groupData, int groupSize, DWORD dwOperationFlags); - void updateServAvatarHash(BYTE *pHash, int size); - void updateServVisibilityCode(BYTE bCode); - - //----| fam_15icqserver.cpp |--------------------------------------------------------- - void handleIcqExtensionsFam(BYTE *pBuffer, size_t wBufferLength, snac_header* pSnacHeader); - - void handleExtensionError(BYTE *buf, size_t wPackLen); - void handleExtensionServerInfo(BYTE *buf, size_t wPackLen, WORD wFlags); - void handleExtensionMetaResponse(BYTE *databuf, size_t wPacketLen, WORD wCookie, WORD wFlags); - - int parseUserInfoRecord(MCONTACT hContact, oscar_tlv *pData, UserInfoRecordItem pRecordDef[], int nRecordDef, int nMaxRecords); - - void handleDirectoryQueryResponse(BYTE *databuf, size_t wPacketLen, WORD wCookie, WORD wReplySubtype, WORD wFlags); - void handleDirectoryUpdateResponse(BYTE *databuf, size_t wPacketLen, WORD wCookie); - - void parseDirectoryUserDetailsData(MCONTACT hContact, oscar_tlv_chain *cDetails, cookie_directory_data *pCookieData, WORD wReplySubType); - void parseDirectorySearchData(oscar_tlv_chain *cDetails, DWORD dwCookie, WORD wReplySubType); - - void parseSearchReplies(unsigned char *databuf, size_t wPacketLen, WORD wCookie, WORD wReplySubtype, BYTE bResultCode); - void parseUserInfoUpdateAck(WORD wCookie, WORD wReplySubtype, BYTE bResultCode); - - void ReleaseSearchCookie(DWORD dwCookie, cookie_search *pCookie); - - //----| fam_17signon.cpp |------------------------------------------------------------ - void handleAuthorizationFam(BYTE *pBuffer, size_t wBufferLength, snac_header *pSnacHeader, serverthread_info *info); - void handleAuthKeyResponse(BYTE *buf, size_t wPacketLen, serverthread_info *info); - - void sendClientAuth(const char *szKey, size_t wKeyLen, BOOL bSecure); - - //----| icq_avatars.cpp |------------------------------------------------------------- - mir_cs m_avatarsMutex; - LIST m_arAvatars; - - BOOL m_avatarsConnectionPending; - avatars_server_connection *m_avatarsConnection; - - void requestAvatarConnection(); - void __cdecl AvatarThread(avatars_server_connection *pInfo); - - void handleAvatarOwnerHash(BYTE bFlags, BYTE *pData, size_t nDataLen); - void handleAvatarContactHash(DWORD dwUIN, char *szUID, MCONTACT hContact, BYTE *pHash, size_t nHashLen); - - wchar_t* GetOwnAvatarFileName(); - void GetFullAvatarFileName(int dwUin, const char *szUid, int dwFormat, wchar_t *pszDest, size_t cbLen); - void GetAvatarFileName(int dwUin, const char *szUid, wchar_t *pszDest, size_t cbLen); - int IsAvatarChanged(MCONTACT hContact, const BYTE *pHash, size_t nHashLen); - - int GetAvatarData(MCONTACT hContact, DWORD dwUin, const char *szUid, const BYTE *hash, size_t hashlen, const wchar_t *file); - int SetAvatarData(MCONTACT hContact, WORD wRef, const BYTE *data, size_t datalen); - - void StartAvatarThread(HNETLIBCONN hConn, char* cookie, size_t cookieLen); - void StopAvatarThread(); - - //----| icq_clients.cpp |------------------------------------------------------------- - const char* detectUserClient(MCONTACT hContact, int nIsICQ, WORD wUserClass, DWORD dwOnlineSince, const char *szCurrentClient, WORD wVersion, DWORD dwFT1, DWORD dwFT2, DWORD dwFT3, DWORD dwDirectCookie, DWORD dwWebPort, BYTE *caps, size_t wLen, BYTE *bClientId, char *szClientBuf); - - //----| icq_db.cpp |------------------------------------------------------------------ - MEVENT AddEvent(MCONTACT hContact, WORD wType, DWORD dwTime, DWORD flags, size_t cbBlob, PBYTE pBlob); - int IsICQContact(MCONTACT hContact); - - int getSetting(MCONTACT hContact, const char *szSetting, DBVARIANT *dbv); - double getSettingDouble(MCONTACT hContact, const char *szSetting, double dDef); - int getSettingStringStatic(MCONTACT hContact, const char *szSetting, char *dest, size_t dest_len); - char* getSettingStringUtf(MCONTACT hContact, const char *szModule, const char *szSetting, char *szDef); - char* getSettingStringUtf(MCONTACT hContact, const char *szSetting, char *szDef); - int getContactUid(MCONTACT hContact, DWORD *pdwUin, uid_str *ppszUid); - DWORD getContactUin(MCONTACT hContact); - WORD getContactStatus(MCONTACT hContact); - char* getContactCListGroup(MCONTACT hContact); - - int setSettingDouble(MCONTACT hContact, const char *szSetting, double dValue); - int setSettingBlob(MCONTACT hContact, const char *szSetting, const BYTE *pValue, size_t cbValue); - int setContactHidden(MCONTACT hContact, BYTE bHidden); - void setStatusMsgVar(MCONTACT hContact, char* szStatusMsg, bool isAnsi); - - //----| icq_direct.cpp |-------------------------------------------------------------- - mir_cs directConnListMutex; - LIST directConns; - - mir_cs expectedFileRecvMutex; - LIST expectedFileRecvs; - - void __cdecl icq_directThread(struct directthreadstartinfo* dtsi); - - void handleDirectPacket(directconnect* dc, PBYTE buf, size_t wLen); - void sendPeerInit_v78(directconnect* dc); - void sendPeerInitAck(directconnect* dc); - void sendPeerMsgInit(directconnect* dc, DWORD dwSeq); - void sendPeerFileInit(directconnect* dc); - int sendDirectPacket(directconnect* dc, icq_packet* pkt); - - void CloseContactDirectConns(MCONTACT hContact); - directconnect* FindFileTransferDC(filetransfer* ft); - filetransfer* FindExpectedFileRecv(DWORD dwUin, DWORD dwTotalSize); - BOOL IsDirectConnectionOpen(MCONTACT hContact, int type, int bPassive); - void OpenDirectConnection(MCONTACT hContact, int type, void* pvExtra); - void CloseDirectConnection(directconnect *dc); - int SendDirectMessage(MCONTACT hContact, icq_packet *pkt); - - //----| icq_directmsg.cpp |----------------------------------------------------------- - void handleDirectMessage(directconnect* dc, PBYTE buf, size_t wLen); - void handleDirectGreetingMessage(directconnect* dc, PBYTE buf, size_t wLen, WORD wCommand, WORD wCookie, BYTE bMsgType, BYTE bMsgFlags, WORD wStatus, WORD wFlags); - - //----| icq_filerequests.cpp |-------------------------------------------------------- - filetransfer* CreateFileTransfer(MCONTACT hContact, DWORD dwUin, int nVersion); - - void handleFileAck(PBYTE buf, size_t wLen, DWORD dwUin, DWORD dwCookie, WORD wStatus); - void handleFileRequest(PBYTE buf, DWORD dwUin, DWORD dwCookie, DWORD dwID1, DWORD dwID2, char* pszDescription, int nVersion, BOOL bDC); - void handleDirectCancel(void); - - void icq_CancelFileTransfer(filetransfer* ft); - - //----| icq_filetransfer.cpp |-------------------------------------------------------- - void icq_sendFileResume(filetransfer *ft, int action, const char *szFilename); - - void handleFileTransferPacket(directconnect *dc, PBYTE buf, size_t wLen); - void handleFileTransferIdle(directconnect *dc); - - //----| icq_infoupdate.cpp |---------------------------------------------------------- - mir_cs infoUpdateMutex; - HANDLE hInfoQueueEvent; - int nInfoUserCount; - int bInfoPendingUsers; - BOOL bInfoUpdateEnabled; - BOOL bInfoUpdateRunning; - HANDLE hInfoThread; - DWORD dwInfoActiveRequest; - userinfo m_infoUpdateList[LISTSIZE]; - - void __cdecl InfoUpdateThread(void*); - - void icq_InitInfoUpdate(void); // Queues all outdated users - BOOL icq_QueueUser(MCONTACT hContact); // Queue one UIN to the list for updating - void icq_DequeueUser(DWORD dwUin); // Remove one UIN from the list - void icq_RescanInfoUpdate(); // Add all outdated contacts to the list - void icq_InfoUpdateCleanup(void); // Clean up on exit - void icq_EnableUserLookup(BOOL bEnable); // Enable/disable user info lookups - - //----| log.cpp |----------------------------------------------------------------- - BOOL bErrorBoxVisible; - - void __cdecl icq_LogMessageThread(void* arg); - - void icq_LogMessage(int level, const char *szMsg); - void icq_LogUsingErrorCode(int level, DWORD dwError, const char *szMsg); //szMsg is optional - void icq_LogFatalParam(const char *szMsg, WORD wError); - - //----| icq_packet.cpp |-------------------------------------------------------------- - void ppackLETLVLNTSfromDB(PBYTE *buf, size_t *buflen, const char *szSetting, WORD wType); - void ppackLETLVWordLNTSfromDB(PBYTE *buf, size_t *buflen, WORD w, const char *szSetting, WORD wType); - void ppackLETLVLNTSBytefromDB(PBYTE *buf, size_t *buflen, const char *szSetting, BYTE b, WORD wType); - - void ppackTLVStringFromDB(PBYTE *buf, size_t *buflen, const char *szSetting, WORD wType); - void ppackTLVStringUtfFromDB(PBYTE *buf, size_t *buflen, const char *szSetting, WORD wType); - void ppackTLVDateFromDB(PBYTE *buf, size_t *buflen, const char *szSettingYear, const char *szSettingMonth, const char *szSettingDay, WORD wType); - - int ppackTLVWordStringItemFromDB(PBYTE *buf, size_t *buflen, const char *szSetting, WORD wTypeID, WORD wTypeData, WORD wID); - int ppackTLVWordStringUtfItemFromDB(PBYTE *buf, size_t *buflen, const char *szSetting, WORD wTypeID, WORD wTypeData, WORD wID); - - BOOL unpackUID(BYTE **ppBuf, size_t *pwLen, DWORD *pdwUIN, uid_str *ppszUID); - - //----| icq_popups.cpp |-------------------------------------------------------------- - int ShowPopupMsg(MCONTACT hContact, const char *szTitle, const char *szMsg, BYTE bType); - - //----| icq_proto.cpp |-------------------------------------------------------------- - void __cdecl CheekySearchThread( void* ); - - void __cdecl GetAwayMsgThread( void *pStatusData ); - - char* PrepareStatusNote(int nStatus); - - //----| icq_rates.cpp |--------------------------------------------------------------- - mir_cs m_ratesMutex; - rates *m_rates; - - rates_queue *m_ratesQueue_Request; // rate queue for xtraz requests - rates_queue *m_ratesQueue_Response; // rate queue for msg responses - - int handleRateItem(rates_queue_item *item, int nQueueType = RQT_DEFAULT, int nMinDelay = 0, BOOL bAllowDelay = TRUE); - - //----| icq_server.cpp |-------------------------------------------------------------- - HNETLIBCONN hServerConn; - WORD wListenPort; - WORD wLocalSequence; - UINT serverThreadId; - HANDLE serverThreadHandle; - - __inline bool icqOnline() const - { return (m_iStatus != ID_STATUS_OFFLINE && m_iStatus != ID_STATUS_CONNECTING); - } - - void __cdecl SendPacketAsyncThread(icq_packet* pArgs); - void __cdecl ServerThread(serverthread_start_info *infoParam); - - void icq_serverDisconnect(void); - void icq_login(const char* szPassword); - - int handleServerPackets(BYTE *buf, int len, serverthread_info *info); - void sendServPacket(icq_packet *pPacket); - void sendServPacketAsync(icq_packet *pPacket); - - int IsServerOverRate(WORD wFamily, WORD wCommand, int nLevel); - - //----| icq_servlist.cpp |------------------------------------------------------------ - HANDLE hHookSettingChanged; - HANDLE hHookContactDeleted; - HANDLE hHookCListGroupChange; - mir_cs servlistMutex; - - DWORD* pdwServerIDList; - int nServerIDListCount; - int nServerIDListSize; - - // server-list update board - mir_cs servlistQueueMutex; - int servlistQueueCount; - int servlistQueueSize; - ssiqueueditems **servlistQueueList; - int servlistQueueState; - HANDLE servlistQueueThreadHandle; - int servlistEditCount; - - void servlistBeginOperation(int operationCount, int bImport); - void servlistEndOperation(int operationCount); - - void __cdecl servlistQueueThread(void* queueState); - - void servlistQueueAddGroupItem(servlistgroupitem* pGroupItem, int dwTimeout); - int servlistHandlePrimitives(DWORD dwOperation); - void servlistProcessLogin(); - - void servlistPostPacket(icq_packet* packet, DWORD dwCookie, DWORD dwOperation, DWORD dwTimeout); - void servlistPostPacketDouble(icq_packet* packet1, DWORD dwCookie, DWORD dwOperation, DWORD dwTimeout, icq_packet* packet2, WORD wAction2); - - // server-list pending queue - int servlistPendingCount; - int servlistPendingSize; - servlistpendingitem** servlistPendingList; - - int servlistPendingFindItem(int nType, MCONTACT hContact, const char *pszGroup); - void servlistPendingAddItem(servlistpendingitem* pItem); - servlistpendingitem* servlistPendingRemoveItem(int nType, MCONTACT hContact, const char *pszGroup); - - void servlistPendingAddContactOperation(MCONTACT hContact, LPARAM param, PENDING_CONTACT_CALLBACK callback, DWORD flags); - void servlistPendingAddGroupOperation(const char *pszGroup, LPARAM param, PENDING_GROUP_CALLBACK callback, DWORD flags); - int servlistPendingAddContact(MCONTACT hContact, WORD wContactID, WORD wGroupID, LPARAM param, PENDING_CONTACT_CALLBACK callback, int bDoInline, LPARAM operationParam = 0, PENDING_CONTACT_CALLBACK operationCallback = nullptr); - int servlistPendingAddGroup(const char *pszGroup, WORD wGroupID, LPARAM param, PENDING_GROUP_CALLBACK callback, int bDoInline, LPARAM operationParam = 0, PENDING_GROUP_CALLBACK operationCallback = nullptr); - void servlistPendingRemoveContact(MCONTACT hContact, WORD wContactID, WORD wGroupID, int nResult); - void servlistPendingRemoveGroup(const char *pszGroup, WORD wGroupID, int nResult); - void servlistPendingFlushOperations(); - - // server-list support functions - int nJustAddedCount; - int nJustAddedSize; - MCONTACT* pdwJustAddedList; - - void AddJustAddedContact(MCONTACT hContact); - BOOL IsContactJustAdded(MCONTACT hContact); - void FlushJustAddedContacts(); - - WORD GenerateServerID(int bGroupType, int bFlags, int wCount = 0); - void ReserveServerID(WORD wID, int bGroupType, int bFlags); - void FreeServerID(WORD wID, int bGroupType); - BOOL CheckServerID(WORD wID, unsigned int wCount); - void FlushServerIDs(); - void LoadServerIDs(); - void StoreServerIDs(); - - void* collectGroups(int *count); - void* collectBuddyGroup(WORD wGroupID, int *count); - char* getServListGroupName(WORD wGroupID); - void setServListGroupName(WORD wGroupID, const char *szGroupName); - WORD getServListGroupLinkID(const char *szPath); - void setServListGroupLinkID(const char *szPath, WORD wGroupID); - int IsServerGroupsDefined(); - char* getServListGroupCListPath(WORD wGroupId); - char* getServListUniqueGroupName(const char *szGroupName, int bAlloced); - - int __cdecl servlistCreateGroup_gotParentGroup(const char *szGroup, WORD wGroupID, LPARAM param, int nResult); - int __cdecl servlistCreateGroup_Ready(const char *szGroup, WORD groupID, LPARAM param, int nResult); - void servlistCreateGroup(const char *szGroupPath, LPARAM param, PENDING_GROUP_CALLBACK callback); - - int __cdecl servlistAddContact_gotGroup(const char *szGroup, WORD wGroupID, LPARAM lParam, int nResult); - int __cdecl servlistAddContact_Ready(MCONTACT hContact, WORD wContactID, WORD wGroupID, LPARAM lParam, int nResult); - void servlistAddContact(MCONTACT hContact, const char *pszGroup); - - int __cdecl servlistRemoveContact_Ready(MCONTACT hContact, WORD contactID, WORD groupID, LPARAM lParam, int nResult); - void servlistRemoveContact(MCONTACT hContact); - - int __cdecl servlistMoveContact_gotTargetGroup(const char *szGroup, WORD wNewGroupID, LPARAM lParam, int nResult); - int __cdecl servlistMoveContact_Ready(MCONTACT hContact, WORD contactID, WORD groupID, LPARAM lParam, int nResult); - void servlistMoveContact(MCONTACT hContact, const char *pszNewGroup); - - int __cdecl servlistUpdateContact_Ready(MCONTACT hContact, WORD contactID, WORD groupID, LPARAM lParam, int nResult); - void servlistUpdateContact(MCONTACT hContact); - - int __cdecl servlistRenameGroup_Ready(const char *szGroup, WORD wGroupID, LPARAM lParam, int nResult); - void servlistRenameGroup(char *szGroup, WORD wGroupId, char *szNewGroup); - - int __cdecl servlistRemoveGroup_Ready(const char *szGroup, WORD groupID, LPARAM lParam, int nResult); - void servlistRemoveGroup(const char *szGroup, WORD wGroupId); - - void removeGroupPathLinks(WORD wGroupID); - int getServListGroupLevel(WORD wGroupId); - - void resetServContactAuthState(MCONTACT hContact); - - void FlushSrvGroupsCache(); - int getCListGroupExists(const char *szGroup); - int moveContactToCListGroup(MCONTACT hContact, const char *szGroup); /// TODO: this should be DB function - - DWORD icq_sendServerItem(DWORD dwCookie, WORD wAction, WORD wGroupId, WORD wItemId, const char *szName, BYTE *pTLVs, size_t nTlvLength, WORD wItemType, DWORD dwOperation, DWORD dwTimeout, void **doubleObject); - DWORD icq_sendServerContact(MCONTACT hContact, DWORD dwCookie, WORD wAction, WORD wGroupId, WORD wContactId, DWORD dwOperation, DWORD dwTimeout, void **doubleObject); - DWORD icq_sendSimpleItem(DWORD dwCookie, WORD wAction, DWORD dwUin, char* szUID, WORD wGroupId, WORD wItemId, WORD wItemType, DWORD dwOperation, DWORD dwTimeout); - DWORD icq_sendServerGroup(DWORD dwCookie, WORD wAction, WORD wGroupId, const char *szName, void *pContent, int cbContent, DWORD dwOperationFlags); - - DWORD icq_modifyServerPrivacyItem(MCONTACT hContact, DWORD dwUin, char *szUid, WORD wAction, DWORD dwOperation, WORD wItemId, WORD wType); - DWORD icq_removeServerPrivacyItem(MCONTACT hContact, DWORD dwUin, char *szUid, WORD wItemId, WORD wType); - DWORD icq_addServerPrivacyItem(MCONTACT hContact, DWORD dwUin, char *szUid, WORD wItemId, WORD wType); - - int __cdecl ServListDbSettingChanged(WPARAM wParam, LPARAM lParam); - int __cdecl ServListCListGroupChange(WPARAM wParam, LPARAM lParam); - - //----| stdpackets.cpp |---------------------------------------------------------- - void icq_sendCloseConnection(); - - void icq_requestnewfamily(WORD wFamily, void (CIcqProto::*familyhandler)(HNETLIBCONN hConn, char* cookie, size_t cookieLen)); - - void icq_setidle(bool bIsIdle); - void icq_setstatus(WORD wStatus, const char *szStatusNote = nullptr); - DWORD icq_sendGetInfoServ(MCONTACT hContact, DWORD, int); - DWORD icq_sendGetAimProfileServ(MCONTACT hContact, char *szUid); - DWORD icq_sendGetAwayMsgServ(MCONTACT hContact, DWORD, int, WORD); - DWORD icq_sendGetAwayMsgServExt(MCONTACT hContact, DWORD dwUin, char *szUID, int type, WORD wVersion); - DWORD icq_sendGetAimAwayMsgServ(MCONTACT hContact, char *szUID, int type); - void icq_sendSetAimAwayMsgServ(const char *szMsg); - - void icq_sendFileSendServv7(filetransfer* ft, const char *szFiles); - void icq_sendFileSendServv8(filetransfer* ft, const char *szFiles, int nAckType); - - void icq_sendFileAcceptServ(DWORD dwUin, filetransfer *ft, int nAckType); - void icq_sendFileAcceptServv7(DWORD dwUin, DWORD TS1, DWORD TS2, DWORD dwCookie, const char *szFiles, const char *szDescr, DWORD dwTotalSize, WORD wPort, BOOL accepted, int nAckType); - void icq_sendFileAcceptServv8(DWORD dwUin, DWORD TS1, DWORD TS2, DWORD dwCookie, const char *szFiles, const char *szDescr, DWORD dwTotalSize, WORD wPort, BOOL accepted, int nAckType); - - void icq_sendFileDenyServ(DWORD dwUin, filetransfer *ft, const char *szReason, int nAckType); - - DWORD icq_sendAdvancedSearchServ(BYTE *fieldsBuffer, size_t bufferLen); - DWORD icq_changeUserPasswordServ(const char *szPassword); - DWORD icq_changeUserDirectoryInfoServ(const BYTE *pData, size_t wDataLen, BYTE bRequestType); - void icq_sendGenericContact(DWORD dwUin, const char *szUid, WORD wFamily, WORD wSubType); - void icq_sendNewContact(DWORD dwUin, const char *szUid); - void icq_sendRemoveContact(DWORD dwUin, const char *szUid); - void icq_sendChangeVisInvis(MCONTACT hContact, DWORD dwUin, char* szUID, int list, int add); - void icq_sendEntireVisInvisList(int); - void icq_sendAwayMsgReplyServ(DWORD, DWORD, DWORD, WORD, WORD, BYTE, char **); - void icq_sendAwayMsgReplyServExt(DWORD dwUin, char *szUID, DWORD dwMsgID1, DWORD dwMsgID2, WORD wCookie, WORD wVersion, BYTE msgType, char **szMsg); - - DWORD icq_sendSMSServ(const char *szPhoneNumber, const char *szMsg); - void icq_sendMessageCapsServ(DWORD dwUin); - void icq_sendRevokeAuthServ(DWORD dwUin, char *szUid); - void icq_sendGrantAuthServ(DWORD dwUin, const char *szUid, const char *szMsg); - void icq_sendAuthReqServ(DWORD dwUin, char* szUid, const char *szMsg); - void icq_sendAuthResponseServ(DWORD dwUin, char* szUid,int auth,const wchar_t *szReason); - void icq_sendYouWereAddedServ(DWORD,DWORD); - - DWORD sendDirectorySearchPacket(const BYTE *pSearchData, size_t wDataLen, WORD wPage, BOOL bOnlineUsersOnly); - DWORD sendTLVSearchPacket(BYTE bType, char* pSearchDataBuf, WORD wSearchType, size_t wInfoLen, BOOL bOnlineUsersOnly); - void sendOwnerInfoRequest(void); - DWORD sendUserInfoMultiRequest(BYTE *pRequestData, size_t dataLen, int nItems); - - DWORD icq_SendChannel1Message(DWORD dwUin, char *szUID, MCONTACT hContact, char *pszText, cookie_message_data *pCookieData); - DWORD icq_SendChannel1MessageW(DWORD dwUin, char *szUID, MCONTACT hContact, WCHAR *pszText, cookie_message_data *pCookieData); // UTF-16 - DWORD icq_SendChannel2Message(DWORD dwUin, MCONTACT hContact, const char *szMessage, size_t nBodyLength, WORD wPriority, cookie_message_data *pCookieData, char *szCap); - DWORD icq_SendChannel2Contacts(DWORD dwUin, char *szUid, MCONTACT hContact, const char *pData, size_t wDataLen, const char *pNames, size_t wNamesLen, cookie_message_data *pCookieData); - DWORD icq_SendChannel4Message(DWORD dwUin, MCONTACT hContact, BYTE bMsgType, size_t wMsgLen, const char *szMsg, cookie_message_data *pCookieData); - - void icq_sendAdvancedMsgAck(DWORD, DWORD, DWORD, WORD, BYTE, BYTE); - void icq_sendContactsAck(DWORD dwUin, char *szUid, DWORD dwMsgID1, DWORD dwMsgID2); - - void icq_sendReverseReq(directconnect *dc, DWORD dwCookie, cookie_message_data *pCookie); - void icq_sendReverseFailed(directconnect* dc, DWORD dwMsgID1, DWORD dwMsgID2, DWORD dwCookie); - - void icq_sendXtrazRequestServ(DWORD dwUin, DWORD dwCookie, char* szBody, size_t nBodyLen, cookie_message_data *pCookieData); - void icq_sendXtrazResponseServ(DWORD dwUin, DWORD dwMID, DWORD dwMID2, WORD wCookie, char* szBody, size_t nBodyLen, int nType); - - DWORD SearchByUin(DWORD dwUin); - DWORD SearchByNames(const char *pszNick, const char *pszFirstName, const char *pszLastName, WORD wPage); - DWORD SearchByMail(const char *pszEmail); - - DWORD icq_searchAimByEmail(const char* pszEmail, DWORD dwSearchId); - - void oft_sendFileRequest(DWORD dwUin, char *szUid, oscar_filetransfer *ft, const char *pszFiles, DWORD dwLocalInternalIP); - void oft_sendFileAccept(DWORD dwUin, char *szUid, oscar_filetransfer *ft); - void oft_sendFileDeny(DWORD dwUin, char *szUid, oscar_filetransfer *ft); - void oft_sendFileCancel(DWORD dwUin, char *szUid, oscar_filetransfer *ft); - void oft_sendFileResponse(DWORD dwUin, char *szUid, oscar_filetransfer *ft, WORD wResponse); - void oft_sendFileRedirect(DWORD dwUin, char *szUid, oscar_filetransfer *ft, DWORD dwIP, WORD wPort, int bProxy); - - //---- | icq_svcs.cpp |---------------------------------------------------------------- - MCONTACT AddToListByUIN(DWORD dwUin, DWORD dwFlags); - MCONTACT AddToListByUID(const char *szUID, DWORD dwFlags); - - void ICQAddRecvEvent(MCONTACT hContact, WORD wType, PROTORECVEVENT* pre, size_t cbBlob, PBYTE pBlob, DWORD flags); - INT_PTR __cdecl IcqAddCapability(WPARAM wParam, LPARAM lParam); - INT_PTR __cdecl IcqCheckCapability(WPARAM wParam, LPARAM lParam); - - OBJLIST CustomCapList; - - //----| icq_uploadui.cpp |------------------------------------------------------------ - void ShowUploadContactsDialog(void); - - //----| icq_xstatus.cpp |------------------------------------------------------------- - int m_bHideXStatusUI; - int m_bHideXStatusMenu; - int bXStatusExtraIconsReady; - HANDLE hHookExtraIconsRebuild; - HANDLE hHookStatusBuild; - HANDLE hHookExtraIconsApply; - HGENMENU hXStatusItems[XSTATUS_COUNT + 1]; - - void InitXStatusItems(BOOL bAllowStatus); - BYTE getContactXStatus(MCONTACT hContact); - DWORD sendXStatusDetailsRequest(MCONTACT hContact, int bForced); - DWORD requestXStatusDetails(MCONTACT hContact, BOOL bAllowDelay); - HICON getXStatusIcon(int bStatus, UINT flags); - void setXStatusEx(BYTE bXStatus, BYTE bQuiet); - void handleXStatusCaps(DWORD dwUIN, char *szUID, MCONTACT hContact, BYTE *caps, int capsize, char *moods, int moodsize); - void updateServerCustomStatus(int fullUpdate); - - //----| icq_xtraz.cpp |--------------------------------------------------------------- - void handleXtrazNotify(DWORD dwUin, DWORD dwMID, DWORD dwMID2, WORD wCookie, char *szMsg, size_t nMsgLen, BOOL bThruDC); - void handleXtrazNotifyResponse(MCONTACT hContact, WORD wCookie, char* szMsg); - - void handleXtrazInvitation(DWORD dwUin, char *szMsg, BOOL bThruDC); - void handleXtrazData(DWORD dwUin, char *szMsg, BOOL bThruDC); - - DWORD SendXtrazNotifyRequest(MCONTACT hContact, char *szQuery, char *szNotify, int bForced); - void SendXtrazNotifyResponse(DWORD dwUin, DWORD dwMID, DWORD dwMID2, WORD wCookie, char *szResponse, size_t nResponseLen, BOOL bThruDC); - - //----| init.cpp |-------------------------------------------------------------------- - void UpdateGlobalSettings(); - - //----| loginpassword.cpp |----------------------------------------------------------- - void RequestPassword(); - - //----| oscar_filetransfer.cpp |------------------------------------------------------ - mir_cs oftMutex; - LIST m_arFileTransfers; - - oscar_filetransfer* CreateOscarTransfer(); - filetransfer *CreateIcqFileTransfer(); - void SafeReleaseFileTransfer(basic_filetransfer **ft); - oscar_filetransfer* FindOscarTransfer(MCONTACT hContact, DWORD dwID1, DWORD dwID2); - - oscar_listener* CreateOscarListener(oscar_filetransfer *ft, NETLIBNEWCONNECTIONPROC_V2 handler); - void ReleaseOscarListener(oscar_listener **pListener); - - void OpenOscarConnection(MCONTACT hContact, oscar_filetransfer *ft, int type); - void CloseOscarConnection(oscar_connection *oc); - int CreateOscarProxyConnection(oscar_connection *oc); - - int IsValidFileTransfer(basic_filetransfer *ft); - int IsValidOscarTransfer(basic_filetransfer *ft); - - void handleRecvServMsgOFT(BYTE *buf, size_t wLen, DWORD dwUin, char *szUID, DWORD dwID1, DWORD dwID2, WORD wCommand); - void handleRecvServResponseOFT(BYTE *buf, size_t wLen, DWORD dwUin, char *szUID, void* ft); - - HANDLE oftInitTransfer(MCONTACT hContact, DWORD dwUin, char *szUid, const wchar_t **pszFiles, const wchar_t *szDescription); - HANDLE oftFileAllow(MCONTACT hContact, HANDLE hTransfer, const wchar_t *szPath); - DWORD oftFileDeny(MCONTACT hContact, HANDLE hTransfer, const wchar_t *szReason); - DWORD oftFileCancel(MCONTACT hContact, HANDLE hTransfer); - void oftFileResume(oscar_filetransfer *ft, int action, const wchar_t *szFilename); - - void sendOscarPacket(oscar_connection *oc, icq_packet *packet); - void handleOFT2FramePacket(oscar_connection *oc, WORD datatype, BYTE *pBuffer, size_t wLen); - void sendOFT2FramePacket(oscar_connection *oc, WORD datatype); - - void proxy_sendInitTunnel(oscar_connection *oc); - void proxy_sendJoinTunnel(oscar_connection *oc, WORD wPort); - - //----| stdpackets.cpp |-------------------------------------------------------------- - void __cdecl oft_connectionThread(void *otsi); - - int oft_handlePackets(oscar_connection *oc, BYTE *buf, size_t len); - int oft_handleFileData(oscar_connection *oc, BYTE *buf, size_t len); - int oft_handleProxyData(oscar_connection *oc, BYTE *buf, size_t len); - void oft_sendFileData(oscar_connection *oc); - void oft_sendPeerInit(oscar_connection *oc); - void oft_sendFileReply(DWORD dwUin, char *szUid, oscar_filetransfer *ft, WORD wResult); - - //----| upload.cpp |------------------------------------------------------------------ - int StringToListItemId(const char *szSetting,int def); - - //----| utilities.cpp |--------------------------------------------------------------- - char* ConvertMsgToUserSpecificAnsi(MCONTACT hContact, const char* szMsg); - - template - char* GetUserStoredPassword(char(&szBuffer)[cbSize]); - char* GetUserPassword(BOOL bAlways); - WORD GetMyStatusFlags(); - - DWORD ReportGenericSendError(MCONTACT hContact, int nType, const char* szErrorMsg); - void SetCurrentStatus(int nStatus); - - void __cdecl ProtocolAckThread(icq_ack_args* pArguments); - void SendProtoAck(MCONTACT hContact, DWORD dwCookie, int nAckResult, int nAckType, char* pszMessage); - - int NetLog_Direct(const char *fmt,...); - int NetLog_Uni(BOOL bDC, const char *fmt,...); - - mir_cs contactsCacheMutex; - LIST contactsCache; - - void AddToContactsCache(MCONTACT hContact, DWORD dwUin, const char *szUid); - void DeleteFromContactsCache(MCONTACT hContact); - void InitContactsCache(); - void UninitContactsCache(); - - void AddToSpammerList(DWORD dwUIN); - BOOL IsOnSpammerList(DWORD dwUIN); - - HNETLIBBIND NetLib_BindPort(NETLIBNEWCONNECTIONPROC_V2 pFunc, void* lParam, WORD *pwPort, DWORD *pdwIntIP); - - MCONTACT HandleFromCacheByUid(DWORD dwUin, const char *szUid); - MCONTACT HContactFromUIN(DWORD dwUin, int *Added); - MCONTACT HContactFromUID(DWORD dwUin, const char *szUid, int *Added); - MCONTACT HContactFromAuthEvent(MEVENT hEvent); - - void ResetSettingsOnListReload(); - void ResetSettingsOnConnect(); - void ResetSettingsOnLoad(); - - int IsMetaInfoChanged(MCONTACT hContact); - - char *setStatusNoteText, *setStatusMoodData; - void __cdecl SetStatusNoteThread(void *pArguments); - int SetStatusNote(const char *szStatusNote, DWORD dwDelay, int bForced); - int SetStatusMood(const char *szMoodData, DWORD dwDelay); - - void writeDbInfoSettingTLVStringUtf(MCONTACT hContact, const char *szSetting, oscar_tlv_chain *chain, WORD wTlv); - void writeDbInfoSettingTLVWord(MCONTACT hContact, const char *szSetting, oscar_tlv_chain *chain, WORD wTlv); - void writeDbInfoSettingTLVByte(MCONTACT hContact, const char *szSetting, oscar_tlv_chain *chain, WORD wTlv); - void writeDbInfoSettingTLVDouble(MCONTACT hContact, const char *szSetting, oscar_tlv_chain *chain, WORD wTlv); - void writeDbInfoSettingTLVDate(MCONTACT hContact, const char *szSettingYear, const char *szSettingMonth, const char *szSettingDay, oscar_tlv_chain *chain, WORD wTlv); - void writeDbInfoSettingTLVBlob(MCONTACT hContact, const char *szSetting, oscar_tlv_chain *chain, WORD wTlv); - - char** MirandaStatusToAwayMsg(int nStatus); - - bool validateStatusMessageRequest(MCONTACT hContact, WORD byMessageType); -}; - -struct CMPlugin : public ACCPROTOPLUGIN -{ - CMPlugin(); - - int Load() override; - int Unload() override; -}; - -#endif diff --git a/protocols/IcqOscarJ/src/icq_rates.cpp b/protocols/IcqOscarJ/src/icq_rates.cpp deleted file mode 100644 index 16851055e5..0000000000 --- a/protocols/IcqOscarJ/src/icq_rates.cpp +++ /dev/null @@ -1,445 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// Rate Management stuff -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -// -// Rate Level 1 Management -///////////////////////////// - -rates::rates(CIcqProto *ppro, BYTE *pBuffer, size_t wLen) -{ - nGroups = 0; - memset(&groups, 0, MAX_RATES_GROUP_COUNT * sizeof(rates_group)); - this->ppro = ppro; - - // Parse Rate Data Block - WORD wCount; - unpackWord(&pBuffer, &wCount); - wLen -= 2; - - if (wCount > MAX_RATES_GROUP_COUNT) { - // just sanity check - ppro->debugLogA("Rates: Error: Data packet contains too many rate groups!"); - wCount = MAX_RATES_GROUP_COUNT; - } - - nGroups = wCount; - // Parse Group details - int i; - for (i = 0; i < wCount; i++) { - rates_group *pGroup = &groups[i]; - - if (wLen >= 35) { - pBuffer += 2; // Group ID - unpackDWord(&pBuffer, &pGroup->dwWindowSize); - unpackDWord(&pBuffer, &pGroup->dwClearLevel); - unpackDWord(&pBuffer, &pGroup->dwAlertLevel); - unpackDWord(&pBuffer, &pGroup->dwLimitLevel); - pBuffer += 8; - unpackDWord(&pBuffer, &pGroup->dwMaxLevel); - pBuffer += 5; - wLen -= 35; - } - else { // packet broken, put some basic defaults - pGroup->dwWindowSize = 10; - pGroup->dwMaxLevel = 5000; - } - pGroup->rCurrentLevel = pGroup->dwMaxLevel; - } - // Parse Group associated pairs - for (i = 0; i < wCount; i++) { - rates_group *pGroup = &groups[i]; - - if (wLen < 4) - break; - - pBuffer += 2; // Group ID - WORD wNum; - unpackWord(&pBuffer, &wNum); - wLen -= 4; - if (wLen < (size_t)wNum * 4) - break; - - pGroup->nPairs = wNum; - pGroup->pPairs = (WORD*)SAFE_MALLOC(wNum * 4); - for (size_t n = 0; n < (size_t)wNum * 2; n++) { - WORD wItem; - unpackWord(&pBuffer, &wItem); - pGroup->pPairs[n] = wItem; - } - - wLen -= wNum * 4; - } -} - -rates::~rates() -{ - for (int i = 0; i < nGroups; i++) - SAFE_FREE((void**)&groups[i].pPairs); - - nGroups = 0; -} - -WORD rates::getGroupFromSNAC(WORD wFamily, WORD wCommand) -{ - if (this) { - for (int i = 0; i < nGroups; i++) { - rates_group* pGroup = &groups[i]; - - for (int j = 0; j < 2 * pGroup->nPairs; j += 2) { - if (pGroup->pPairs[j] == wFamily && pGroup->pPairs[j + 1] == wCommand) { // we found the group - return (WORD)(i + 1); - } - } - } - // Legacy ICQ server - } - - return 0; // Failure -} - -WORD rates::getGroupFromPacket(icq_packet *pPacket) -{ - if (this) { - if (pPacket->nChannel == ICQ_DATA_CHAN && pPacket->wLen >= 0x10) { - WORD wFamily, wCommand; - BYTE *pBuf = pPacket->pData + 6; - - unpackWord(&pBuf, &wFamily); - unpackWord(&pBuf, &wCommand); - - return getGroupFromSNAC(wFamily, wCommand); - } - } - return 0; -} - -rates_group* rates::getGroup(WORD wGroup) -{ - if (this && wGroup && wGroup <= nGroups) - return &groups[wGroup - 1]; - - return nullptr; -} - -int rates::getNextRateLevel(WORD wGroup) -{ - rates_group *pGroup = getGroup(wGroup); - - if (pGroup) { - int nLevel = pGroup->rCurrentLevel*(pGroup->dwWindowSize - 1) / pGroup->dwWindowSize + (GetTickCount() - pGroup->tCurrentLevel) / pGroup->dwWindowSize; - - return nLevel < (int)pGroup->dwMaxLevel ? nLevel : pGroup->dwMaxLevel; - } - return -1; // Failure -} - -int rates::getDelayToLimitLevel(WORD wGroup, int nLevel) -{ - rates_group *pGroup = getGroup(wGroup); - - if (pGroup) - return (getLimitLevel(wGroup, nLevel) - pGroup->rCurrentLevel)*pGroup->dwWindowSize + pGroup->rCurrentLevel; - - return 0; // Failure -} - -void rates::packetSent(icq_packet *pPacket) -{ - if (this) { - WORD wGroup = getGroupFromPacket(pPacket); - - if (wGroup) - updateLevel(wGroup, getNextRateLevel(wGroup)); - } -} - -void rates::updateLevel(WORD wGroup, int nLevel) -{ - rates_group *pGroup = getGroup(wGroup); - - if (pGroup) { - pGroup->rCurrentLevel = nLevel; - pGroup->tCurrentLevel = GetTickCount(); - - ppro->debugLogA("Rates: New level %d for #%d", nLevel, wGroup); - } -} - -int rates::getLimitLevel(WORD wGroup, int nLevel) -{ - rates_group *pGroup = getGroup(wGroup); - - if (pGroup) { - switch (nLevel) { - case RML_CLEAR: - return pGroup->dwClearLevel; - - case RML_ALERT: - return pGroup->dwAlertLevel; - - case RML_LIMIT: - return pGroup->dwLimitLevel; - - case RML_IDLE_10: - return pGroup->dwClearLevel + ((pGroup->dwMaxLevel - pGroup->dwClearLevel) / 10); - - case RML_IDLE_30: - return pGroup->dwClearLevel + (3 * (pGroup->dwMaxLevel - pGroup->dwClearLevel) / 10); - - case RML_IDLE_50: - return pGroup->dwClearLevel + ((pGroup->dwMaxLevel - pGroup->dwClearLevel) / 2); - - case RML_IDLE_70: - return pGroup->dwClearLevel + (7 * (pGroup->dwMaxLevel - pGroup->dwClearLevel) / 10); - } - } - return 9999; // some high number - without rates we allow anything -} - -void rates::initAckPacket(icq_packet *pPacket) -{ - serverPacketInit(pPacket, 10 + nGroups * sizeof(WORD)); - packFNACHeader(pPacket, ICQ_SERVICE_FAMILY, ICQ_CLIENT_RATE_ACK); - for (WORD wGroup = 1; wGroup <= nGroups; wGroup++) - packWord(pPacket, wGroup); -} - -// -// Rate Level 2 Management -///////////////////////////// - -rates_queue_item::rates_queue_item(CIcqProto *ppro, WORD wGroup) : bCreated(FALSE), dwUin(0), szUid(nullptr) -{ - this->ppro = ppro; - this->wGroup = wGroup; -} - -rates_queue_item::~rates_queue_item() -{ - if (bCreated) { - SAFE_FREE(&szUid); - bCreated = FALSE; - } -} - -BOOL rates_queue_item::isEqual(rates_queue_item *pItem) -{ - // the same event (equal address of _vftable) for the same contact - return (pItem->hContact == this->hContact) && (*(void**)pItem == *(void**)this); -} - -rates_queue_item* rates_queue_item::copyItem(rates_queue_item *pDest) -{ - if (!pDest) - pDest = new rates_queue_item(ppro, wGroup); - - pDest->hContact = hContact; - pDest->dwUin = dwUin; - pDest->szUid = dwUin ? null_strdup(szUid) : nullptr; - pDest->bCreated = TRUE; - - return pDest; -} - -void rates_queue_item::execute() -{ - ppro->debugLogA("Rates: Error executing abstract event."); -} - -BOOL rates_queue_item::isOverRate(int nLevel) -{ - mir_cslock l(ppro->m_ratesMutex); - - if (ppro->m_rates) - return ppro->m_rates->getNextRateLevel(wGroup) < ppro->m_rates->getLimitLevel(wGroup, nLevel); - - return FALSE; -} - -rates_queue::rates_queue(CIcqProto *_ppro, const char *_descr, int nLimitLevel, int nWaitLevel, int nDuplicates) : - lstPending(1) -{ - ppro = _ppro; - szDescr = _descr; - limitLevel = nLimitLevel; - waitLevel = nWaitLevel; - duplicates = nDuplicates; -} - -rates_queue::~rates_queue() -{ - cleanup(); -} - -static void rateDelayThread(rates_queue *pQueue) -{ - Thread_SetName("ICQ: rateDelayThread"); - pQueue->handleDelay(); -} - -void rates_queue::initDelay(int nDelay) -{ - ppro->debugLogA("Rates: Delay %dms", nDelay); - - scheduledDelay = nDelay; - mir_forkThread(rateDelayThread, this); -} - -void rates_queue::handleDelay() -{ - SleepEx(scheduledDelay, TRUE); - - if (!Miranda_IsTerminated()) - processQueue(); -} - -void rates_queue::cleanup() -{ - mir_cslock l(csLists); - for (auto &it : lstPending) - delete it; - lstPending.destroy(); -} - -void rates_queue::processQueue() -{ - if (!ppro->icqOnline()) - return; - - // take from queue, execute - mir_cslockfull l(csLists); - if (lstPending.getCount() == 0) - return; - - rates_queue_item *item = lstPending[0]; - { - mir_cslockfull rlck(ppro->m_ratesMutex); - if (item->isOverRate(limitLevel)) { // the rate is higher, keep sleeping - int nDelay = ppro->m_rates->getDelayToLimitLevel(item->wGroup, ppro->m_rates->getLimitLevel(item->wGroup, waitLevel)); - - l.unlock(); - rlck.unlock(); - if (nDelay < 10) nDelay = 10; - initDelay(nDelay); - return; - } - } - - lstPending.remove(int(0)); - bool bSetupTimer = lstPending.getCount() != 0; - - l.unlock(); - - if (ppro->icqOnline()) { - ppro->debugLogA("Rates: Resuming %s.", szDescr); - item->execute(); - } - else ppro->debugLogA("Rates: Discarding %s.", szDescr); - - if (bSetupTimer) { // in queue remained some items, setup timer - int nDelay; - { - mir_cslockfull rlck(ppro->m_ratesMutex); - nDelay = ppro->m_rates->getDelayToLimitLevel(item->wGroup, waitLevel); - } - - if (nDelay < 10) nDelay = 10; - initDelay(nDelay); - } - delete item; -} - -void rates_queue::putItem(rates_queue_item *pItem, int nMinDelay) -{ - if (!ppro->icqOnline()) - return; - - ppro->debugLogA("Rates: Delaying %s.", szDescr); - { - mir_cslock l(csLists); - - auto T = lstPending.rev_iter(); - for (auto &it : T) { - if (it->isEqual(pItem)) { - if (duplicates == 1) // keep existing, ignore new - return; - - if (duplicates == -1) { // discard existing, append new item - delete it; - lstPending.remove(T.indexOf(&it)); - } - } - } - - lstPending.insert(pItem->copyItem()); - } - - if (lstPending.getCount() != 1) - return; - - // queue was empty setup timer - int nDelay; - { - mir_cslock rlck(ppro->m_ratesMutex); - nDelay = ppro->m_rates->getDelayToLimitLevel(pItem->wGroup, waitLevel); - } - - if (nDelay < 10) nDelay = 10; - if (nDelay < nMinDelay) nDelay = nMinDelay; - initDelay(nDelay); -} - -int CIcqProto::handleRateItem(rates_queue_item *item, int nQueueType, int nMinDelay, BOOL bAllowDelay) -{ - rates_queue *pQueue = nullptr; - { - mir_cslock rlck(m_ratesMutex); - switch (nQueueType) { - case RQT_REQUEST: - pQueue = m_ratesQueue_Request; - break; - case RQT_RESPONSE: - pQueue = m_ratesQueue_Response; - break; - } - - if (pQueue) { - if (bAllowDelay && (item->isOverRate(pQueue->waitLevel) || nMinDelay)) { - // limit reached or min delay configured, add to queue - pQueue->putItem(item, nMinDelay); - return 1; - } - } - } - - item->execute(); - return 0; -} diff --git a/protocols/IcqOscarJ/src/icq_rates.h b/protocols/IcqOscarJ/src/icq_rates.h deleted file mode 100644 index addd97725c..0000000000 --- a/protocols/IcqOscarJ/src/icq_rates.h +++ /dev/null @@ -1,148 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// Rate management -// ----------------------------------------------------------------------------- - -#ifndef __ICQ_RATES_H -#define __ICQ_RATES_H - -#define MAX_RATES_GROUP_COUNT 5 - -struct rates_group -{ - DWORD dwWindowSize; - DWORD dwClearLevel; - DWORD dwAlertLevel; - DWORD dwLimitLevel; - DWORD dwMaxLevel; - - // current level - int rCurrentLevel; - int tCurrentLevel; - - // links - WORD *pPairs; - int nPairs; -}; - -struct rates : public MZeroedObject -{ -private: - CIcqProto * ppro; - int nGroups; - rates_group groups[MAX_RATES_GROUP_COUNT]; - - rates_group *getGroup(WORD wGroup); -public: - rates(CIcqProto *ppro, BYTE *pBuffer, size_t wLen); - ~rates(); - - WORD getGroupFromSNAC(WORD wFamily, WORD wCommand); - WORD getGroupFromPacket(icq_packet *pPacket); - - int getLimitLevel(WORD wGroup, int nLevel); - int getDelayToLimitLevel(WORD wGroup, int nLevel); - int getNextRateLevel(WORD wGroup); - - void packetSent(icq_packet *pPacket); - void updateLevel(WORD wGroup, int nLevel); - - void initAckPacket(icq_packet *pPacket); -}; - -#define RML_CLEAR 0x01 -#define RML_ALERT 0x02 -#define RML_LIMIT 0x03 -#define RML_IDLE_10 0x10 -#define RML_IDLE_30 0x11 -#define RML_IDLE_50 0x12 -#define RML_IDLE_70 0x13 - -// Rates - Level 2 - -// queue types -#define RQT_DEFAULT 0 // standard - pushes all items without much delay -#define RQT_REQUEST 1 // request - pushes only first item on duplicity -#define RQT_RESPONSE 2 // response - pushes only last item on duplicity - -// -// generic queue item -// -struct rates_queue_item : public MZeroedObject -{ - friend class rates_queue; -protected: - CIcqProto * ppro; - BOOL bCreated; - WORD wGroup; - - virtual BOOL isEqual(rates_queue_item *pItem); - virtual rates_queue_item* copyItem(rates_queue_item *pDest = nullptr); -public: - rates_queue_item(CIcqProto *ppro, WORD wGroup); - virtual ~rates_queue_item(); - - BOOL isOverRate(int nLevel); - - virtual void execute(); - - MCONTACT hContact; - DWORD dwUin; - char *szUid; -}; - -// -// generic item queue (FIFO) -// -class rates_queue : public MZeroedObject -{ - CIcqProto *ppro; - const char *szDescr; - int duplicates; - int scheduledDelay; - - mir_cs csLists; // we need to be thread safe - LIST lstPending; - -protected: - void cleanup(); - void initDelay(int nDelay); - void processQueue(); - -public: - rates_queue(CIcqProto *ppro, const char *szDescr, int nLimitLevel, int nWaitLevel, int nDuplicates); - ~rates_queue(); - - void putItem(rates_queue_item *pItem, int nMinDelay); - void handleDelay(); - - int limitLevel; // RML_* - int waitLevel; -}; - - -#endif /* __ICQ_RATES_H */ diff --git a/protocols/IcqOscarJ/src/icq_server.cpp b/protocols/IcqOscarJ/src/icq_server.cpp deleted file mode 100644 index 00ada57843..0000000000 --- a/protocols/IcqOscarJ/src/icq_server.cpp +++ /dev/null @@ -1,403 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// Manages main server connection, low-level communication -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -void icq_newConnectionReceived(HNETLIBCONN hNewConnection, DWORD dwRemoteIP, void *pExtra); - -///////////////////////////////////////////////////////////////////////////////////////// -// ICQ Server thread - -void __cdecl CIcqProto::ServerThread(serverthread_start_info *infoParam) -{ - Thread_SetName("ICQ: ServerThread"); - - serverthread_info info = { 0 }; - info.isLoginServer = info.bReinitRecver = true; - info.wAuthKeyLen = infoParam->wPassLen; - null_strcpy((char*)info.szAuthKey, infoParam->szPass, info.wAuthKeyLen); - // store server port - info.wServerPort = infoParam->nloc.wPort; - - srand(time(0)); - - ResetSettingsOnConnect(); - - // Connect to the login server - debugLogA("Authenticating to server"); - { - NETLIBOPENCONNECTION nloc = infoParam->nloc; - nloc.timeout = 6; - if (m_bGatewayMode) - nloc.flags |= NLOCF_HTTPGATEWAY; - - hServerConn = NetLib_OpenConnection(m_hNetlibUser, nullptr, &nloc); - - SAFE_FREE((void**)&nloc.szHost); - SAFE_FREE((void**)&infoParam); - - if (hServerConn && m_bSecureConnection) { - if (!Netlib_StartSsl(hServerConn, nullptr)) { - icq_LogMessage(LOG_ERROR, LPGEN("Unable to connect to ICQ login server, SSL could not be negotiated")); - SetCurrentStatus(ID_STATUS_OFFLINE); - NetLib_CloseConnection(&hServerConn, TRUE); - return; - } - } - } - - // Login error - if (hServerConn == nullptr) { - DWORD dwError = GetLastError(); - - SetCurrentStatus(ID_STATUS_OFFLINE); - - icq_LogUsingErrorCode(LOG_ERROR, dwError, LPGEN("Unable to connect to ICQ login server")); - return; - } - - // Initialize direct connection ports - DWORD dwInternalIP; - BYTE bConstInternalIP = getByte("ConstRealIP", 0); - - info.hDirectBoundPort = NetLib_BindPort(icq_newConnectionReceived, this, &wListenPort, &dwInternalIP); - if (!info.hDirectBoundPort) { - icq_LogUsingErrorCode(LOG_WARNING, GetLastError(), LPGEN("Miranda was unable to allocate a port to listen for direct peer-to-peer connections between clients. You will be able to use most of the ICQ network without problems but you may be unable to send or receive files.\n\nIf you have a firewall this may be blocking Miranda, in which case you should configure your firewall to leave some ports open and tell Miranda which ports to use in Options -> Network -> ICQ client-to-client connections.")); - wListenPort = 0; - if (!bConstInternalIP) - delSetting("RealIP"); - } - else if (!bConstInternalIP) - setDword("RealIP", dwInternalIP); - - // Initialize rate limiting queues - { - mir_cslock l(m_ratesMutex); - m_ratesQueue_Request = new rates_queue(this, "request", RML_IDLE_30, RML_IDLE_50, 1); - m_ratesQueue_Response = new rates_queue(this, "response", RML_IDLE_10, RML_IDLE_30, -1); - } - - StartKeepAlive(&info); - - // This is the "infinite" loop that receives the packets from the ICQ server - NETLIBPACKETRECVER packetRecv; - info.hPacketRecver = Netlib_CreatePacketReceiver(hServerConn, 0x2400); - - while (serverThreadHandle) { - if (info.bReinitRecver) { // we reconnected, reinit struct - info.bReinitRecver = false; - memset(&packetRecv, 0, sizeof(packetRecv)); - packetRecv.dwTimeout = 1000; - } - - int recvResult = Netlib_GetMorePackets(info.hPacketRecver, &packetRecv); - if (recvResult == 0) { - debugLogA("Clean closure of server socket"); - break; - } - - if (recvResult == SOCKET_ERROR) { - DWORD dwError = GetLastError(); - if (dwError == ERROR_TIMEOUT) { - if (m_iDesiredStatus == ID_STATUS_OFFLINE) - break; - - CheckKeepAlive(&info); - continue; - } - if (dwError == WSAESHUTDOWN) // ok, we're going offline - break; - - debugLogA("Abortive closure of server socket, error: %d", dwError); - break; - } - - // Deal with the packet - CheckKeepAlive(&info); - packetRecv.bytesUsed = handleServerPackets(packetRecv.buffer, packetRecv.bytesAvailable, &info); - } - serverThreadHandle = nullptr; - - // Time to shutdown - debugLogA("Closing server connections..."); - NetLib_CloseConnection(&hServerConn, TRUE); - - // Close the packet receiver (connection may still be open) - NetLib_SafeCloseHandle(&info.hPacketRecver); - - // Close DC port - Netlib_CloseHandle(info.hDirectBoundPort); - info.hDirectBoundPort = nullptr; - - // disable auto info-update thread - icq_EnableUserLookup(FALSE); - - if (m_iStatus != ID_STATUS_OFFLINE && m_iDesiredStatus != ID_STATUS_OFFLINE) { - if (!info.bLoggedIn) - icq_LogMessage(LOG_FATAL, LPGEN("Connection failed.\nLogin sequence failed for unknown reason.\nTry again later.")); - - // set flag indicating we were kicked out - m_bConnectionLost = true; - - SetCurrentStatus(ID_STATUS_OFFLINE); - } - - // signal keep-alive thread to stop - StopKeepAlive(&info); - - // Close all open DC connections - CloseContactDirectConns(NULL); - - // Close avatar connection if any - StopAvatarThread(); - - // Offline all contacts - for (auto &hContact : AccContacts()) { - if (getContactStatus(hContact) == ID_STATUS_OFFLINE) - continue; - - setWord(hContact, "Status", ID_STATUS_OFFLINE); - - DWORD dwUIN; - uid_str szUID; - if (!getContactUid(hContact, &dwUIN, &szUID)) { - char tmp = 0; - handleXStatusCaps(dwUIN, szUID, hContact, (BYTE*)&tmp, 0, &tmp, 0); - } - } - - setDword("LogonTS", 0); // clear logon time - - servlistPendingFlushOperations(); // clear pending operations list - - // release rates queues - { - mir_cslock l(m_ratesMutex); - delete m_ratesQueue_Request; m_ratesQueue_Request = nullptr; - delete m_ratesQueue_Response; m_ratesQueue_Response = nullptr; - delete m_rates; m_rates = nullptr; - } - - FlushServerIDs(); // clear server IDs list - - debugLogA("%s thread ended.", "Server"); -} - -void CIcqProto::icq_serverDisconnect() -{ - if (!hServerConn) - return; - - debugLogA("Server shutdown requested"); - Netlib_Shutdown(hServerConn); - - debugLogA("Dropping server thread"); - if (serverThreadHandle) { - debugLogA("Closing server thread handle: %08p", serverThreadHandle); - CloseHandle(serverThreadHandle); - serverThreadHandle = nullptr; - } - - SetCurrentStatus(ID_STATUS_OFFLINE); -} - -int CIcqProto::handleServerPackets(BYTE *buf, int len, serverthread_info *info) -{ - BYTE channel; - WORD sequence; - WORD datalen; - int bytesUsed = 0; - - while (len > 0) { - if (info->bReinitRecver) - break; - - // All FLAPS begin with 0x2a - if (*buf++ != FLAP_MARKER) - break; - - if (len < 6) - break; - - unpackByte(&buf, &channel); - unpackWord(&buf, &sequence); - unpackWord(&buf, &datalen); - - if (len < 6 + datalen) - break; - - debugLogA("Server FLAP: Channel %u, Seq %u, Length %u bytes", channel, sequence, datalen); - - switch (channel) { - case ICQ_LOGIN_CHAN: - handleLoginChannel(buf, datalen, info); - break; - - case ICQ_DATA_CHAN: - handleDataChannel(buf, datalen, info); - break; - - case ICQ_ERROR_CHAN: - handleErrorChannel(buf, datalen); - break; - - case ICQ_CLOSE_CHAN: - handleCloseChannel(buf, datalen, info); - break; // we need this for walking thru proxy - - case ICQ_PING_CHAN: - handlePingChannel(buf, datalen); - break; - - default: - debugLogA("Warning: Unhandled Server FLAP Channel: Channel %u, Seq %u, Length %u bytes", channel, sequence, datalen); - break; - } - - /* Increase pointers so we can check for more FLAPs */ - buf += datalen; - len -= (datalen + 6); - bytesUsed += (datalen + 6); - } - - return bytesUsed; -} - - -void CIcqProto::sendServPacket(icq_packet *pPacket) -{ - // make sure to have the connection handle - mir_cslockfull l(connectionHandleMutex); - - if (hServerConn) { - // This critsec makes sure that the sequence order doesn't get screwed up - int nSendResult; - { - mir_cslock slck(localSeqMutex); - - // :IMPORTANT: - // The FLAP sequence must be a WORD. When it reaches 0xFFFF it should wrap to - // 0x0000, otherwise we'll get kicked by server. - wLocalSequence++; - - // Pack sequence number - pPacket->pData[2] = ((wLocalSequence & 0xff00) >> 8); - pPacket->pData[3] = (wLocalSequence & 0x00ff); - - nSendResult = Netlib_Send(hServerConn, (const char *)pPacket->pData, pPacket->wLen, 0); - } - l.unlock(); - - // Send error - if (nSendResult == SOCKET_ERROR) { - DWORD dwErrorCode = GetLastError(); - if (dwErrorCode != WSAESHUTDOWN) - icq_LogUsingErrorCode(LOG_ERROR, GetLastError(), LPGEN("Your connection with the ICQ server was abortively closed")); - icq_serverDisconnect(); - } - else { // Rates management - mir_cslock r(m_ratesMutex); - m_rates->packetSent(pPacket); - } - } - else debugLogA("Error: Failed to send packet (no connection)"); - - SAFE_FREE((void**)&pPacket->pData); -} - - -void __cdecl CIcqProto::SendPacketAsyncThread(icq_packet* pkt) -{ - Thread_SetName("ICQ: SendPacketAsyncThread"); - sendServPacket(pkt); - SAFE_FREE((void**)&pkt); -} - - -void CIcqProto::sendServPacketAsync(icq_packet *packet) -{ - icq_packet *pPacket; - - pPacket = (icq_packet*)SAFE_MALLOC(sizeof(icq_packet)); // This will be freed in the new thread - memcpy(pPacket, packet, sizeof(icq_packet)); - - ForkThread((MyThreadFunc)&CIcqProto::SendPacketAsyncThread, pPacket); -} - - -int CIcqProto::IsServerOverRate(WORD wFamily, WORD wCommand, int nLevel) -{ - mir_cslock l(m_ratesMutex); - - if (m_rates) { - WORD wGroup = m_rates->getGroupFromSNAC(wFamily, wCommand); - - // check if the rate is not over specified level - if (m_rates->getNextRateLevel(wGroup) < m_rates->getLimitLevel(wGroup, nLevel)) - return TRUE; - } - - return FALSE; -} - - -///////////////////////////////////////////////////////////////////////////////////////// -// ICQ Server thread - -void CIcqProto::icq_login(const char* szPassword) -{ - DWORD dwUin = getContactUin(NULL); - serverthread_start_info* stsi = (serverthread_start_info*)SAFE_MALLOC(sizeof(serverthread_start_info)); - - // Server host name - char szServer[MAX_PATH]; - if (getSettingStringStatic(NULL, "OscarServer", szServer, MAX_PATH)) - stsi->nloc.szHost = null_strdup(m_bSecureConnection ? DEFAULT_SERVER_HOST_SSL : DEFAULT_SERVER_HOST); - else - stsi->nloc.szHost = null_strdup(szServer); - - // Server port - stsi->nloc.wPort = getWord("OscarPort", m_bSecureConnection ? DEFAULT_SERVER_PORT_SSL : DEFAULT_SERVER_PORT); - if (stsi->nloc.wPort == 0) - stsi->nloc.wPort = RandRange(1024, 65535); - - // User password - stsi->wPassLen = mir_strlen(szPassword); - null_strcpy(stsi->szPass, szPassword, stsi->wPassLen); - - // Randomize sequence - wLocalSequence = generate_flap_sequence(); - - m_dwLocalUIN = dwUin; - - // Initialize members - m_avatarsConnectionPending = TRUE; - - serverThreadHandle = ForkThreadEx((MyThreadFunc)&CIcqProto::ServerThread, stsi, &serverThreadId); -} diff --git a/protocols/IcqOscarJ/src/icq_server.h b/protocols/IcqOscarJ/src/icq_server.h deleted file mode 100644 index 2cc012f80f..0000000000 --- a/protocols/IcqOscarJ/src/icq_server.h +++ /dev/null @@ -1,62 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2009 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// Declarations for server thread -// ----------------------------------------------------------------------------- - -#ifndef __ICQ_SERVER_H -#define __ICQ_SERVER_H - -struct serverthread_start_info -{ - NETLIBOPENCONNECTION nloc; - size_t wPassLen; - char szPass[128]; -}; - -struct serverthread_info -{ - BYTE szAuthKey[20]; - size_t wAuthKeyLen; - WORD wServerPort; - char *newServer; - BYTE *cookieData; - int cookieDataLen; - int newServerSSL; - time_t tmPing; // timestamp of the next ping - - bool isLoginServer; - bool isMigrating; - bool isNewServerReady; - bool bLoggedIn; - bool bReinitRecver; - bool bMyAvatarInited; - - HANDLE hPacketRecver; - HNETLIBBIND hDirectBoundPort; -}; - -#endif /* __ICQ_SERVER_H */ diff --git a/protocols/IcqOscarJ/src/icq_servlist.cpp b/protocols/IcqOscarJ/src/icq_servlist.cpp deleted file mode 100644 index ee70e8de8a..0000000000 --- a/protocols/IcqOscarJ/src/icq_servlist.cpp +++ /dev/null @@ -1,2349 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// Functions that handles list of used server IDs, sends low-level packets for SSI information -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -// SERVER-LIST UPDATE BOARD -// - -void CIcqProto::servlistBeginOperation(int operationCount, int bImport) -{ - // check if we should send operation begin packet - if (operationCount) { - if (!servlistEditCount) - icq_sendServerBeginOperation(bImport); - - // update count of active operations - servlistEditCount += operationCount; - debugLogA("Server-List: Begin operation processed (%d operations active)", servlistEditCount); - } -} - -void CIcqProto::servlistEndOperation(int operationCount) -{ - if (operationCount) { - if (operationCount > servlistEditCount) { // sanity check - debugLogA("Error: Server-List End operation is not paired!"); - operationCount = servlistEditCount; - } - // update count of active operations - servlistEditCount -= operationCount; - // check if we should send operation end packet - if (!servlistEditCount) - icq_sendServerEndOperation(); - - debugLogA("Server-List: End operation processed (%d operations active)", servlistEditCount); - } -} - -void __cdecl CIcqProto::servlistQueueThread(void *param) -{ - debugLogA("Server-List: Starting Update board."); - Thread_SetName("ICQ: servlistQueueThread"); - - int *queueState = (int*)param; - SleepEx(50, FALSE); - - // handle server-list requests queue - mir_cslockfull l(servlistQueueMutex); - - while (servlistQueueCount) { - ssiqueueditems* pItem = nullptr; - int bItemDouble; - WORD wItemAction; - icq_packet groupPacket = { 0 }; - icq_packet groupPacket2 = { 0 }; - int nEndOperations; - - // first check if the state is calm - while (*queueState) { - int i; - time_t tNow = time(0); - int bFound = FALSE; - - for (i = 0; i < servlistQueueCount; i++) { // check if we do not have some expired items to handle, otherwise keep sleeping - if ((servlistQueueList[i]->tAdded + servlistQueueList[i]->dwTimeout) < tNow) { // got expired item, stop sleep even when changes goes on - bFound = TRUE; - break; - } - } - if (bFound) break; - // reset queue state, keep sleeping - *queueState = FALSE; - l.unlock(); - SleepEx(100, TRUE); - l.lock(); - } - if (!icqOnline()) { // do not try to send packets if offline - l.unlock(); - SleepEx(100, TRUE); - l.lock(); - continue; - } - - debugLogA("Server-List: %d items in queue.", servlistQueueCount); - - // take the oldest item (keep the board FIFO) - pItem = servlistQueueList[0]; // take first (queue contains at least one item here) - wItemAction = (WORD)(pItem->pItems[0]->dwOperation & SSOF_ACTIONMASK); - bItemDouble = pItem->pItems[0]->dwOperation & SSOG_DOUBLE; - - // check item rate - too high -> sleep - { - mir_cslockfull rlck(m_ratesMutex); - - WORD wRateGroup = m_rates->getGroupFromSNAC(ICQ_LISTS_FAMILY, wItemAction); - int nRateLevel = bItemDouble ? RML_IDLE_30 : RML_IDLE_10; - - while (m_rates->getNextRateLevel(wRateGroup) < m_rates->getLimitLevel(wRateGroup, nRateLevel)) { // the rate is higher, keep sleeping - int nDelay = m_rates->getDelayToLimitLevel(wRateGroup, nRateLevel); - - rlck.unlock(); - // do not keep the queue frozen - l.unlock(); - if (nDelay < 10) - nDelay = 10; - - debugLogA("Server-List: Delaying %dms [Rates]", nDelay); - - SleepEx(nDelay, FALSE); - // check if the rate is now ok - l.lock(); - rlck.lock(); - } - } - - { - // setup group packet(s) & cookie - int totalSize = 0; - int i; - cookie_servlist_action *pGroupCookie; - DWORD dwGroupCookie; - // determine the total size of the packet - for (i = 0; i < pItem->nItems; i++) - totalSize += pItem->pItems[i]->packet.wLen - 0x10; - - // process begin & end operation flags - { - int bImportOperation = FALSE; - int nBeginOperations = 0; - - nEndOperations = 0; - for (i = 0; i < pItem->nItems; i++) { // collect begin & end operation flags - if (pItem->pItems[i]->dwOperation & SSOF_BEGIN_OPERATION) - nBeginOperations++; - if (pItem->pItems[i]->dwOperation & SSOF_END_OPERATION) - nEndOperations++; - // check if the operation is import - if (pItem->pItems[i]->dwOperation & SSOF_IMPORT_OPERATION) - bImportOperation = TRUE; - } - // really begin operation if requested - if (nBeginOperations) - servlistBeginOperation(nBeginOperations, bImportOperation); - } - - if (pItem->nItems > 1) { // pack all packet's data, create group cookie - pGroupCookie = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action)); - pGroupCookie->dwAction = SSA_ACTION_GROUP; - pGroupCookie->dwGroupCount = pItem->nItems; - pGroupCookie->pGroupItems = (cookie_servlist_action**)SAFE_MALLOC(pItem->nItems * sizeof(cookie_servlist_action*)); - for (i = 0; i < pItem->nItems; i++) { // build group cookie data - assign cookies datas - pGroupCookie->pGroupItems[i] = pItem->pItems[i]->cookie; - // release the separate cookie id - FreeCookieByData(CKT_SERVERLIST, pItem->pItems[i]->cookie); - } - // allocate cookie id - dwGroupCookie = AllocateCookie(CKT_SERVERLIST, wItemAction, 0, pGroupCookie); - // prepare packet data - serverPacketInit(&groupPacket, totalSize + 0x0A); // FLAP size added inside - packFNACHeader(&groupPacket, ICQ_LISTS_FAMILY, wItemAction, 0, dwGroupCookie); - for (i = 0; i < pItem->nItems; i++) - packBuffer(&groupPacket, pItem->pItems[i]->packet.pData + 0x10, pItem->pItems[i]->packet.wLen - 0x10); - - if (bItemDouble) { // prepare second packet - wItemAction = ((servlistgroupitemdouble*)(pItem->pItems[0]))->wAction2; - totalSize = 0; - // determine the total size of the packet - for (i = 0; i < pItem->nItems; i++) - totalSize += ((servlistgroupitemdouble*)(pItem->pItems[i]))->packet2.wLen - 0x10; - - pGroupCookie = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action)); - pGroupCookie->dwAction = SSA_ACTION_GROUP; - pGroupCookie->dwGroupCount = pItem->nItems; - pGroupCookie->pGroupItems = (cookie_servlist_action**)SAFE_MALLOC(pItem->nItems * sizeof(cookie_servlist_action*)); - for (i = 0; i < pItem->nItems; i++) - pGroupCookie->pGroupItems[i] = pItem->pItems[i]->cookie; - // allocate cookie id - dwGroupCookie = AllocateCookie(CKT_SERVERLIST, wItemAction, 0, pGroupCookie); - // prepare packet data - serverPacketInit(&groupPacket2, totalSize + 0x0A); // FLAP size added inside - packFNACHeader(&groupPacket2, ICQ_LISTS_FAMILY, wItemAction, 0, dwGroupCookie); - for (i = 0; i < pItem->nItems; i++) - packBuffer(&groupPacket2, ((servlistgroupitemdouble*)(pItem->pItems[i]))->packet2.pData + 0x10, ((servlistgroupitemdouble*)(pItem->pItems[i]))->packet2.wLen - 0x10); - } - } - else { // just send the one packet, do not create action group - pGroupCookie = pItem->pItems[0]->cookie; - memcpy(&groupPacket, &pItem->pItems[0]->packet, sizeof(icq_packet)); - if (bItemDouble) - memcpy(&groupPacket2, &((servlistgroupitemdouble*)(pItem->pItems[0]))->packet2, sizeof(icq_packet)); - } - - // remove grouped item from queue & release grouped item - servlistQueueCount--; - servlistQueueList[0] = servlistQueueList[servlistQueueCount]; - - for (i = 0; i < pItem->nItems; i++) { // release memory - if (pItem->nItems > 1) { // free the packet only if we created the group packet - SAFE_FREE((void**)&pItem->pItems[i]->packet.pData); - if (pItem->pItems[i]->dwOperation & SSOG_DOUBLE) - SAFE_FREE((void**)&((servlistgroupitemdouble*)(pItem->pItems[i]))->packet2.pData); - } - SAFE_FREE((void**)&pItem->pItems[i]); - } - SAFE_FREE((void**)&pItem); - // resize the queue - if (servlistQueueSize > servlistQueueCount + 6) { - servlistQueueSize -= 4; - servlistQueueList = (ssiqueueditems**)SAFE_REALLOC(servlistQueueList, servlistQueueSize * sizeof(ssiqueueditems*)); - } - } - l.unlock(); - // send group packet - sendServPacket(&groupPacket); - // send second group packet (if present) - if (bItemDouble) - sendServPacket(&groupPacket2); - // process end operation marks - if (nEndOperations) - servlistEndOperation(nEndOperations); - // loose the loop a bit - SleepEx(100, TRUE); - l.lock(); - } - - // clean-up thread - CloseHandle(servlistQueueThreadHandle); - servlistQueueThreadHandle = nullptr; - - debugLogA("Server-List: Update Board ending."); -} - -void CIcqProto::servlistQueueAddGroupItem(servlistgroupitem* pGroupItem, int dwTimeout) -{ - mir_cslock l(servlistQueueMutex); - - // add the packet to queue - DWORD dwMark = pGroupItem->dwOperation & SSOF_GROUPINGMASK; - ssiqueueditems* pItem = nullptr; - - // try to find compatible item - for (int i = 0; i < servlistQueueCount; i++) { - if ((servlistQueueList[i]->pItems[0]->dwOperation & SSOF_GROUPINGMASK) == dwMark && servlistQueueList[i]->nItems < MAX_SERVLIST_PACKET_ITEMS) { // found compatible item, check if it does not contain operation for the same server-list item - pItem = servlistQueueList[i]; - - for (int j = 0; j < pItem->nItems; j++) - if (pItem->pItems[j]->cookie->wContactId == pGroupItem->cookie->wContactId && pItem->pItems[j]->cookie->wGroupId == pGroupItem->cookie->wGroupId) { - pItem = nullptr; - break; - } - - // cannot send two operations for the same server-list record in one packet, look for another - if (!pItem) - continue; - - debugLogA("Server-List: Adding packet to item #%d with operation %x.", i, servlistQueueList[i]->pItems[0]->dwOperation); - break; - } - } - if (!pItem) { // compatible item was not found, create new one, add to queue - pItem = (ssiqueueditems*)SAFE_MALLOC(sizeof(ssiqueueditems)); - pItem->tAdded = time(0); - pItem->dwTimeout = dwTimeout; - - if (servlistQueueCount == servlistQueueSize) { // resize the queue - it is too small - servlistQueueSize += 4; - servlistQueueList = (ssiqueueditems**)SAFE_REALLOC(servlistQueueList, servlistQueueSize * sizeof(ssiqueueditems*)); - } - // really add to queue - servlistQueueList[servlistQueueCount++] = pItem; - - debugLogA("Server-List: Adding new item to queue."); - } - else if (pItem->dwTimeout > dwTimeout) { - // if the timeout of currently added packet is shorter, update the previous one - pItem->dwTimeout = dwTimeout; - } - // add GroupItem to queueditems (pItem) - pItem->pItems[pItem->nItems++] = pGroupItem; - - // wake up board thread (keep sleeping or start new one) - if (!servlistQueueThreadHandle) - // create new board thread - servlistQueueThreadHandle = ForkThreadEx(&CIcqProto::servlistQueueThread, &servlistQueueState, nullptr); - else // signal thread, that queue was changed during sleep - servlistQueueState = TRUE; -} - -int CIcqProto::servlistHandlePrimitives(DWORD dwOperation) -{ - if (dwOperation & SSO_BEGIN_OPERATION) { // operation starting, no action ready yet - servlistBeginOperation(1, dwOperation & SSOF_IMPORT_OPERATION); - return TRUE; - } - if (dwOperation & SSO_END_OPERATION) { // operation ending without action - servlistEndOperation(1); - return TRUE; - } - - return FALSE; -} - -void CIcqProto::servlistPostPacket(icq_packet* packet, DWORD dwCookie, DWORD dwOperation, DWORD dwTimeout) -{ - cookie_servlist_action* pCookie; - - if (servlistHandlePrimitives(dwOperation)) - return; - - if (!FindCookie(dwCookie, nullptr, (void**)&pCookie)) - return; // invalid cookie - - if (dwOperation & SSOF_SEND_DIRECTLY) { // send directly - this is for some special cases - // begin operation if requested - if (dwOperation & SSOF_BEGIN_OPERATION) - servlistBeginOperation(1, dwOperation & SSOF_IMPORT_OPERATION); - - // send the packet - sendServPacket(packet); - - // end operation if requested - if (dwOperation & SSOF_END_OPERATION) - servlistEndOperation(1); - } - else { // add to server-list update board - // prepare group item - servlistgroupitem *pGroupItem = (servlistgroupitem*)SAFE_MALLOC(sizeof(servlistgroupitem)); - pGroupItem->dwOperation = dwOperation; - pGroupItem->cookie = pCookie; - // packet data are alloced, keep them until they are sent - memcpy(&pGroupItem->packet, packet, sizeof(icq_packet)); - - servlistQueueAddGroupItem(pGroupItem, dwTimeout); - } -} - -void CIcqProto::servlistPostPacketDouble(icq_packet* packet1, DWORD dwCookie, DWORD dwOperation, DWORD dwTimeout, icq_packet* packet2, WORD wAction2) -{ - cookie_servlist_action* pCookie; - - if (servlistHandlePrimitives(dwOperation)) - return; - - if (!FindCookie(dwCookie, nullptr, (void**)&pCookie)) - return; // invalid cookie - - if (dwOperation & SSOF_SEND_DIRECTLY) { // send directly - this is for some special cases - // begin operation if requested - if (dwOperation & SSOF_BEGIN_OPERATION) - servlistBeginOperation(1, dwOperation & SSOF_IMPORT_OPERATION); - - // send the packets - sendServPacket(packet1); - sendServPacket(packet2); - - // end operation if requested - if (dwOperation & SSOF_END_OPERATION) - servlistEndOperation(1); - } - else { // add to server-list update board - servlistgroupitemdouble* pGroupItem; - - // prepare group item - pGroupItem = (servlistgroupitemdouble*)SAFE_MALLOC(sizeof(servlistgroupitemdouble)); - pGroupItem->dwOperation = dwOperation; - pGroupItem->cookie = pCookie; - pGroupItem->wAction2 = wAction2; - // packets data are alloced, keep them until they are sent - memcpy(&pGroupItem->packet, packet1, sizeof(icq_packet)); - memcpy(&pGroupItem->packet2, packet2, sizeof(icq_packet)); - - servlistQueueAddGroupItem((servlistgroupitem*)pGroupItem, dwTimeout); - } -} - -void CIcqProto::servlistProcessLogin() -{ - // reset edit state counter - servlistEditCount = 0; - - /// TODO: preserve queue state in DB! restore here! - - // if the server-list queue contains items and thread is not running, start it - if (servlistQueueCount && !servlistQueueThreadHandle) - servlistQueueThreadHandle = ForkThreadEx(&CIcqProto::servlistQueueThread, &servlistQueueState, nullptr); -} - -// HERE ENDS SERVER-LIST UPDATE BOARD IMPLEMENTATION // -/////////////////////////////////////////////////////// -//===================================================// - -// PENDING SERVER-LIST OPERATIONS -// -#define ITEM_PENDING_CONTACT 0x01 -#define ITEM_PENDING_GROUP 0x02 - -#define CALLBACK_RESULT_CONTINUE 0x00 -#define CALLBACK_RESULT_POSTPONE 0x0D -#define CALLBACK_RESULT_PURGE 0x10 - - -#define SPOF_AUTO_CREATE_ITEM 0x01 - -int CIcqProto::servlistPendingFindItem(int nType, MCONTACT hContact, const char *pszGroup) -{ - if (servlistPendingList) - for (int i = 0; i < servlistPendingCount; i++) - if (servlistPendingList[i]->nType == nType) - if (((nType == ITEM_PENDING_CONTACT) && (servlistPendingList[i]->hContact == hContact)) || - ((nType == ITEM_PENDING_GROUP) && (!mir_strcmp(servlistPendingList[i]->szGroup, pszGroup)))) - return i; - - return -1; -} - -void CIcqProto::servlistPendingAddItem(servlistpendingitem *pItem) -{ - if (servlistPendingCount >= servlistPendingSize) { // add new - servlistPendingSize += 10; - servlistPendingList = (servlistpendingitem**)SAFE_REALLOC(servlistPendingList, servlistPendingSize * sizeof(servlistpendingitem*)); - } - - servlistPendingList[servlistPendingCount++] = pItem; -} - -servlistpendingitem* CIcqProto::servlistPendingRemoveItem(int nType, MCONTACT hContact, const char *pszGroup) -{ - // unregister pending item, trigger pending operations - int iItem; - servlistpendingitem *pItem = nullptr; - - mir_cslock l(servlistMutex); - - if ((iItem = servlistPendingFindItem(nType, hContact, pszGroup)) != -1) { // found, remove from the pending list - pItem = servlistPendingList[iItem]; - - servlistPendingList[iItem] = servlistPendingList[--servlistPendingCount]; - - if (servlistPendingCount + 10 < servlistPendingSize) { - servlistPendingSize -= 5; - servlistPendingList = (servlistpendingitem**)SAFE_REALLOC(servlistPendingList, servlistPendingSize * sizeof(servlistpendingitem*)); - } - - // was the first operation was created automatically to postpone ItemAdd? - if (pItem->operations && pItem->operations[0].flags & SPOF_AUTO_CREATE_ITEM) { // yes, add new item - servlistpendingitem *pNewItem = (servlistpendingitem*)SAFE_MALLOC(sizeof(servlistpendingitem)); - - if (pNewItem) { // move the remaining operations - if (pItem->nType == ITEM_PENDING_CONTACT) - debugLogA("Server-List: Resuming contact %x operation.", pItem->hContact); - else - debugLogA("Server-List: Resuming group \"%s\" operation.", pItem->szGroup); - - pNewItem->nType = pItem->nType; - pNewItem->hContact = pItem->hContact; - pNewItem->szGroup = null_strdup(pItem->szGroup); - pNewItem->wContactID = pItem->wContactID; - pNewItem->wGroupID = pItem->wGroupID; - pNewItem->operationsCount = pItem->operationsCount - 1; - pNewItem->operations = (servlistpendingoperation*)SAFE_MALLOC(pNewItem->operationsCount * sizeof(servlistpendingoperation)); - memcpy(pNewItem->operations, pItem->operations + 1, pNewItem->operationsCount * sizeof(servlistpendingoperation)); - pItem->operationsCount = 1; - - servlistPendingAddItem(pNewItem); - // clear the flag - pItem->operations[0].flags &= ~SPOF_AUTO_CREATE_ITEM; - } - } - } - else debugLogA("Server-List Error: Trying to remove non-existing pending %s.", nType == ITEM_PENDING_CONTACT ? "contact" : "group"); - - return pItem; -} - - -void CIcqProto::servlistPendingAddContactOperation(MCONTACT hContact, LPARAM param, PENDING_CONTACT_CALLBACK callback, DWORD flags) -{ - // add postponed operation (add contact, update contact, regroup resume, etc.) - // - after contact is added - int iItem; - servlistpendingitem *pItem = nullptr; - - mir_cslock l(servlistMutex); - - if ((iItem = servlistPendingFindItem(ITEM_PENDING_CONTACT, hContact, nullptr)) != -1) - pItem = servlistPendingList[iItem]; - - if (pItem) { - int iOperation = pItem->operationsCount++; - - pItem->operations = (servlistpendingoperation*)SAFE_REALLOC(pItem->operations, pItem->operationsCount * sizeof(servlistpendingoperation)); - pItem->operations[iOperation].param = param; - pItem->operations[iOperation].callback = (PENDING_GROUP_CALLBACK)callback; - pItem->operations[iOperation].flags = flags; - } - else debugLogA("Server-List Error: Trying to add pending operation to a non existing contact."); -} - -void CIcqProto::servlistPendingAddGroupOperation(const char *pszGroup, LPARAM param, PENDING_GROUP_CALLBACK callback, DWORD flags) -{ - // add postponed operation - after group is added - int iItem; - servlistpendingitem *pItem = nullptr; - - mir_cslock l(servlistMutex); - - if ((iItem = servlistPendingFindItem(ITEM_PENDING_GROUP, NULL, pszGroup)) != -1) - pItem = servlistPendingList[iItem]; - - if (pItem) { - int iOperation = pItem->operationsCount++; - - pItem->operations = (servlistpendingoperation*)SAFE_REALLOC(pItem->operations, pItem->operationsCount * sizeof(servlistpendingoperation)); - pItem->operations[iOperation].param = param; - pItem->operations[iOperation].callback = callback; - pItem->operations[iOperation].flags = flags; - } - else debugLogA("Server-List Error: Trying to add pending operation to a non existing group."); -} - -int CIcqProto::servlistPendingAddContact(MCONTACT hContact, WORD wContactID, WORD wGroupID, LPARAM param, PENDING_CONTACT_CALLBACK callback, int bDoInline, LPARAM operationParam, PENDING_CONTACT_CALLBACK operationCallback) -{ - int iItem; - servlistpendingitem *pItem = nullptr; - - mir_cslockfull l(servlistMutex); - - if ((iItem = servlistPendingFindItem(ITEM_PENDING_CONTACT, hContact, nullptr)) != -1) - pItem = servlistPendingList[iItem]; - - if (pItem) { - debugLogA("Server-List: Pending contact %x already in list; adding as operation.", hContact); - - servlistPendingAddContactOperation(hContact, param, callback, SPOF_AUTO_CREATE_ITEM); - - if (operationCallback) - servlistPendingAddContactOperation(hContact, operationParam, operationCallback, 0); - return 0; // Pending - } - - debugLogA("Server-List: Starting contact %x operation.", hContact); - - pItem = (servlistpendingitem *)SAFE_MALLOC(sizeof(servlistpendingitem)); - pItem->nType = ITEM_PENDING_CONTACT; - pItem->hContact = hContact; - pItem->wContactID = wContactID; - pItem->wGroupID = wGroupID; - - servlistPendingAddItem(pItem); - - if (operationCallback) - servlistPendingAddContactOperation(hContact, operationParam, operationCallback, 0); - - l.unlock(); - - if (bDoInline) // not postponed, called directly if requested - (this->*callback)(hContact, wContactID, wGroupID, param, PENDING_RESULT_INLINE); - - return 1; // Ready -} - -int CIcqProto::servlistPendingAddGroup(const char *pszGroup, WORD wGroupID, LPARAM param, PENDING_GROUP_CALLBACK callback, int bDoInline, LPARAM operationParam, PENDING_GROUP_CALLBACK operationCallback) -{ - int iItem; - servlistpendingitem *pItem = nullptr; - - mir_cslockfull l(servlistMutex); - - if ((iItem = servlistPendingFindItem(ITEM_PENDING_GROUP, NULL, pszGroup)) != -1) - pItem = servlistPendingList[iItem]; - - if (pItem) { - debugLogA("Server-List: Pending group \"%s\" already in list; adding as operation.", pszGroup); - - servlistPendingAddGroupOperation(pszGroup, param, callback, SPOF_AUTO_CREATE_ITEM); - - if (operationCallback) - servlistPendingAddGroupOperation(pszGroup, operationParam, operationCallback, 0); - return 0; // Pending - } - - debugLogA("Server-List: Starting group \"%s\" operation.", pszGroup); - - pItem = (servlistpendingitem *)SAFE_MALLOC(sizeof(servlistpendingitem)); - pItem->nType = ITEM_PENDING_GROUP; - pItem->szGroup = null_strdup(pszGroup); - pItem->wGroupID = wGroupID; - - servlistPendingAddItem(pItem); - - if (operationCallback) - servlistPendingAddGroupOperation(pszGroup, operationParam, operationCallback, 0); - - l.unlock(); - - if (bDoInline) // not postponed, called directly if requested - (this->*callback)(pszGroup, wGroupID, param, PENDING_RESULT_INLINE); - - return 1; // Ready -} - -void CIcqProto::servlistPendingRemoveContact(MCONTACT hContact, WORD wContactID, WORD wGroupID, int nResult) -{ - debugLogA("Server-List: %s contact %x operation.", (nResult != PENDING_RESULT_PURGE) ? "Ending" : "Purging", hContact); - - servlistpendingitem *pItem = servlistPendingRemoveItem(ITEM_PENDING_CONTACT, hContact, nullptr); - - if (pItem) { // process pending operations - if (pItem->operations) { - for (int i = 0; i < pItem->operationsCount; i++) { - int nCallbackState = (this->*(PENDING_CONTACT_CALLBACK)(pItem->operations[i].callback))(hContact, wContactID, wGroupID, pItem->operations[i].param, nResult); - - if (nResult != PENDING_RESULT_PURGE && nCallbackState == CALLBACK_RESULT_POSTPONE) { // any following pending operations cannot be processed now, move them to the new pending contact - for (int j = i + 1; j < pItem->operationsCount; j++) - servlistPendingAddContactOperation(hContact, pItem->operations[j].param, (PENDING_CONTACT_CALLBACK)(pItem->operations[j].callback), pItem->operations[j].flags); - break; - } - else if (nCallbackState == CALLBACK_RESULT_PURGE) // purge all following operations - fatal failure occured - nResult = PENDING_RESULT_PURGE; - } - SAFE_FREE((void**)&pItem->operations); - } - // release item's memory - SAFE_FREE((void**)&pItem); - } - else debugLogA("Server-List Error: Trying to remove a non existing pending contact."); -} - -void CIcqProto::servlistPendingRemoveGroup(const char *pszGroup, WORD wGroupID, int nResult) -{ - debugLogA("Server-List: %s group \"%s\" operation.", (nResult != PENDING_RESULT_PURGE) ? "Ending" : "Purging", pszGroup); - - servlistpendingitem *pItem = servlistPendingRemoveItem(ITEM_PENDING_GROUP, NULL, pszGroup); - - if (pItem) { // process pending operations - if (pItem->operations) { - for (int i = 0; i < pItem->operationsCount; i++) { - int nCallbackState = (this->*pItem->operations[i].callback)(pItem->szGroup, wGroupID, pItem->operations[i].param, nResult); - - if (nResult != PENDING_RESULT_PURGE && nCallbackState == CALLBACK_RESULT_POSTPONE) { // any following pending operations cannot be processed now, move them to the new pending group - for (int j = i + 1; j < pItem->operationsCount; j++) - servlistPendingAddGroupOperation(pItem->szGroup, pItem->operations[j].param, pItem->operations[j].callback, pItem->operations[j].flags); - break; - } - else if (nCallbackState == CALLBACK_RESULT_PURGE) { // purge all following operations - fatal failure occured - nResult = PENDING_RESULT_PURGE; - } - } - SAFE_FREE((void**)&pItem->operations); - } - // release item's memory - SAFE_FREE((void**)&pItem->szGroup); - SAFE_FREE((void**)&pItem); - } - else debugLogA("Server-List Error: Trying to remove a non existing pending group."); -} - -// Remove All pending operations -void CIcqProto::servlistPendingFlushOperations() -{ - mir_cslock l(servlistMutex); - - for (int i = servlistPendingCount; i; i--) { // purge all items - servlistpendingitem *pItem = servlistPendingList[i - 1]; - - if (pItem->nType == ITEM_PENDING_CONTACT) - servlistPendingRemoveContact(pItem->hContact, 0, 0, PENDING_RESULT_PURGE); - else if (pItem->nType == ITEM_PENDING_GROUP) - servlistPendingRemoveGroup(pItem->szGroup, 0, PENDING_RESULT_PURGE); - } - // release the list completely - SAFE_FREE((void**)&servlistPendingList); - servlistPendingCount = 0; - servlistPendingSize = 0; -} - -// END OF SERVER-LIST PENDING OPERATIONS -//// - -// used for adding new contacts to list - sync with visible items -void CIcqProto::AddJustAddedContact(MCONTACT hContact) -{ - mir_cslock l(servlistMutex); - - if (nJustAddedCount >= nJustAddedSize) { - nJustAddedSize += 10; - pdwJustAddedList = (MCONTACT*)SAFE_REALLOC(pdwJustAddedList, nJustAddedSize * sizeof(MCONTACT)); - } - - pdwJustAddedList[nJustAddedCount] = hContact; - nJustAddedCount++; -} - -// was the contact added during this serv-list load -BOOL CIcqProto::IsContactJustAdded(MCONTACT hContact) -{ - mir_cslock l(servlistMutex); - - if (pdwJustAddedList) - for (int i = 0; i < nJustAddedCount; i++) - if (pdwJustAddedList[i] == hContact) - return TRUE; - - return FALSE; -} - - -void CIcqProto::FlushJustAddedContacts() -{ - mir_cslock l(servlistMutex); - - SAFE_FREE((void**)&pdwJustAddedList); - nJustAddedSize = 0; - nJustAddedCount = 0; -} - -// Add a server ID to the list of reserved IDs. -// To speed up the process, no checks is done, if -// you try to reserve an ID twice, it will be added again. -// You should call CheckServerID before reserving an ID. -void CIcqProto::ReserveServerID(WORD wID, int bGroupType, int bFlags) -{ - { mir_cslock l(servlistMutex); - if (nServerIDListCount >= nServerIDListSize) { - nServerIDListSize += 100; - pdwServerIDList = (DWORD*)SAFE_REALLOC(pdwServerIDList, nServerIDListSize * sizeof(DWORD)); - } - - pdwServerIDList[nServerIDListCount] = wID | (bGroupType & 0x00FF0000) | (bFlags & 0xFF000000); - nServerIDListCount++; - } - - if (!bIsSyncingCL) - StoreServerIDs(); -} - -// Remove a server ID from the list of reserved IDs. -// Used for deleting contacts and other modifications. -void CIcqProto::FreeServerID(WORD wID, int bGroupType) -{ - DWORD dwId = wID | (bGroupType & 0x00FF0000); - - mir_cslock l(servlistMutex); - - if (pdwServerIDList) { - for (int i = 0; i < nServerIDListCount; i++) { - if ((pdwServerIDList[i] & 0x00FFFFFF) == dwId) { // we found it, so remove - for (int j = i + 1; j < nServerIDListCount; j++) - pdwServerIDList[j - 1] = pdwServerIDList[j]; - - nServerIDListCount--; - } - } - } -} - -// Returns true if dwID is reserved -BOOL CIcqProto::CheckServerID(WORD wID, unsigned int wCount) -{ - mir_cslock l(servlistMutex); - - if (pdwServerIDList) { - for (int i = 0; i < nServerIDListCount; i++) { - if (((pdwServerIDList[i] & 0xFFFF) >= wID) && ((pdwServerIDList[i] & 0xFFFF) <= wID + wCount)) - return TRUE; - } - } - - return FALSE; -} - -void CIcqProto::FlushServerIDs() -{ - mir_cslock l(servlistMutex); - - SAFE_FREE((void**)&pdwServerIDList); - nServerIDListCount = 0; - nServerIDListSize = 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -struct GroupReserveIdsEnumParam -{ - CIcqProto *ppro; - char *szModule; -}; - -static int GroupReserveIdsEnumProc(const char *szSetting, void *lParam) -{ - if (szSetting && mir_strlen(szSetting) < 5) { - // it is probably server group - GroupReserveIdsEnumParam *param = (GroupReserveIdsEnumParam*)lParam; - char val[MAX_PATH + 2]; // dummy - if (db_get_static(0, param->szModule, szSetting, val, MAX_PATH)) - if (db_get_static_utf(0, param->szModule, szSetting, val, MAX_PATH)) - return 0; // we failed also, invalid setting - - param->ppro->ReserveServerID((WORD)strtoul(szSetting, nullptr, 0x10), SSIT_GROUP, 0); - param->ppro->debugLogA("Loaded group %u:'%s'", strtoul(szSetting, nullptr, 0x10), val); - } - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Load all known server IDs from DB to list - -void CIcqProto::LoadServerIDs() -{ - WORD wSrvID; - int nGroups = 0, nContacts = 0, nPermits = 0, nDenys = 0, nIgnores = 0, nUnhandled = 0; - - mir_cslockfull l(servlistMutex); - if (wSrvID = getWord(DBSETTING_SERVLIST_AVATAR, 0)) - ReserveServerID(wSrvID, SSIT_ITEM, 0); - if (wSrvID = getWord(DBSETTING_SERVLIST_PHOTO, 0)) - ReserveServerID(wSrvID, SSIT_ITEM, 0); - if (wSrvID = getWord(DBSETTING_SERVLIST_PRIVACY, 0)) - ReserveServerID(wSrvID, SSIT_ITEM, 0); - if (wSrvID = getWord(DBSETTING_SERVLIST_METAINFO, 0)) - ReserveServerID(wSrvID, SSIT_ITEM, 0); - if (wSrvID = getWord("SrvImportID", 0)) - ReserveServerID(wSrvID, SSIT_ITEM, 0); - - int nStart = nServerIDListCount; - - char szModule[MAX_PATH]; - mir_snprintf(szModule, "%sSrvGroups", m_szModuleName); - GroupReserveIdsEnumParam param = { this, szModule }; - - db_enum_settings(NULL, &GroupReserveIdsEnumProc, szModule, ¶m); - - nGroups = nServerIDListCount - nStart; - - for (auto &hContact : AccContacts()) { - if (wSrvID = getWord(hContact, DBSETTING_SERVLIST_ID, 0)) { - ReserveServerID(wSrvID, SSIT_ITEM, 0); - nContacts++; - } - if (wSrvID = getWord(hContact, DBSETTING_SERVLIST_DENY, 0)) { - ReserveServerID(wSrvID, SSIT_ITEM, 0); - nDenys++; - } - if (wSrvID = getWord(hContact, DBSETTING_SERVLIST_PERMIT, 0)) { - ReserveServerID(wSrvID, SSIT_ITEM, 0); - nPermits++; - } - if (wSrvID = getWord(hContact, DBSETTING_SERVLIST_IGNORE, 0)) { - ReserveServerID(wSrvID, SSIT_ITEM, 0); - nIgnores++; - } - } - l.unlock(); - - DBVARIANT dbv = { 0 }; - if (!getSetting(NULL, DBSETTING_SERVLIST_UNHANDLED, &dbv)) { - int dataLen = dbv.cpbVal; - BYTE *pData = dbv.pbVal; - - while (dataLen >= 4) { - BYTE bGroupType; - BYTE bFlags; - - unpackLEWord(&pData, &wSrvID); - unpackByte(&pData, &bGroupType); - unpackByte(&pData, &bFlags); - - ReserveServerID(wSrvID, bGroupType, bFlags); - dataLen -= 4; - nUnhandled++; - } - - db_free(&dbv); - } - - debugLogA("Loaded SSI: %d contacts, %d groups, %d permit, %d deny, %d ignore, %d unknown items.", nContacts, nGroups, nPermits, nDenys, nIgnores, nUnhandled); -} - -void CIcqProto::StoreServerIDs() /// TODO: allow delayed -{ - BYTE *pUnhandled = nullptr; - size_t cbUnhandled = 0; - - mir_cslockfull l(servlistMutex); - if (pdwServerIDList) - for (int i = 0; i < nServerIDListCount; i++) - if ((pdwServerIDList[i] & 0xFF000000) == SSIF_UNHANDLED) { - ppackLEWord(&pUnhandled, &cbUnhandled, pdwServerIDList[i] & 0xFFFF); - ppackByte(&pUnhandled, &cbUnhandled, (pdwServerIDList[i] & 0x00FF0000) >> 0x10); - ppackByte(&pUnhandled, &cbUnhandled, (pdwServerIDList[i] & 0xFF000000) >> 0x18); - } - - l.unlock(); - - if (pUnhandled) - setSettingBlob(NULL, DBSETTING_SERVLIST_UNHANDLED, pUnhandled, (int)cbUnhandled); - else - delSetting(DBSETTING_SERVLIST_UNHANDLED); - - SAFE_FREE((void**)&pUnhandled); -} - -// Generate server ID with wCount IDs free after it, for sub-groups. -WORD CIcqProto::GenerateServerID(int bGroupType, int bFlags, int wCount) -{ - WORD wId; - - while (TRUE) { - // Randomize a new ID - // Max value is probably 0x7FFF, lowest value is probably 0x0001 (generated by Icq2Go) - // We use range 0x1000-0x7FFF. - wId = (WORD)RandRange(0x1000, 0x7FFF); - - if (!CheckServerID(wId, wCount)) - break; - } - - ReserveServerID(wId, bGroupType, bFlags); - return wId; -} - -/*********************************************** -* -* --- Low-level packet sending functions --- -* -*/ - -struct doubleServerItemObject -{ - WORD wAction; - icq_packet packet; -}; - -DWORD CIcqProto::icq_sendServerItem(DWORD dwCookie, WORD wAction, WORD wGroupId, WORD wItemId, const char *szName, BYTE *pTLVs, size_t nTlvLength, WORD wItemType, DWORD dwOperation, DWORD dwTimeout, void **doubleObject) -{ - // Prepare item name length - size_t nNameLen = mir_strlen(szName); - - // Build the packet - icq_packet packet; - serverPacketInit(&packet, nNameLen + 20 + nTlvLength); - packFNACHeader(&packet, ICQ_LISTS_FAMILY, wAction, 0, dwCookie); - packWord(&packet, WORD(nNameLen)); - if (nNameLen) - packBuffer(&packet, (LPBYTE)szName, nNameLen); - packWord(&packet, wGroupId); - packWord(&packet, wItemId); - packWord(&packet, wItemType); - packWord(&packet, WORD(nTlvLength)); - if (nTlvLength) - packBuffer(&packet, pTLVs, nTlvLength); - - if (!doubleObject) // Send the packet and return the cookie - servlistPostPacket(&packet, dwCookie, dwOperation | wAction, dwTimeout); - else { - if (*doubleObject) { // Send both packets and return the cookie - doubleServerItemObject* helper = (doubleServerItemObject*)*doubleObject; - - servlistPostPacketDouble(&helper->packet, dwCookie, dwOperation | helper->wAction, dwTimeout, &packet, wAction); - SAFE_FREE(doubleObject); - } - else { // Create helper object, return the cookie - doubleServerItemObject* helper = (doubleServerItemObject*)SAFE_MALLOC(sizeof(doubleServerItemObject)); - - if (helper) { - helper->wAction = wAction; - memcpy(&helper->packet, &packet, sizeof(icq_packet)); - *doubleObject = helper; - } - else // memory alloc failed - return 0; - } - } - - // Force reload of server-list after change - setWord("SrvRecordCount", 0); - - return dwCookie; -} - -DWORD CIcqProto::icq_sendServerContact(MCONTACT hContact, DWORD dwCookie, WORD wAction, WORD wGroupId, WORD wContactId, DWORD dwOperation, DWORD dwTimeout, void **doubleObject) -{ - BYTE *pData = nullptr, *pMetaToken = nullptr, *pMetaTime = nullptr; - int nDataLen = 0, nMetaTokenLen = 0, nMetaTimeLen = 0; - - // Prepare UID - DWORD dwUin; - uid_str szUid; - if (getContactUid(hContact, &dwUin, &szUid)) { - debugLogA("Buddy upload failed (UID missing)."); - return 0; - } - - BYTE bAuth = getByte(hContact, "Auth", 0); - char *szNick = getSettingStringUtf(hContact, "CList", "MyHandle", nullptr); - char *szNote = getSettingStringUtf(hContact, "UserInfo", "MyNotes", nullptr); - - DBVARIANT dbv; - if (!getSetting(hContact, DBSETTING_METAINFO_TOKEN, &dbv)) { - nMetaTokenLen = dbv.cpbVal; - pMetaToken = (BYTE*)_alloca(dbv.cpbVal); - memcpy(pMetaToken, dbv.pbVal, dbv.cpbVal); - - db_free(&dbv); - } - if (!getSetting(hContact, DBSETTING_METAINFO_TIME, &dbv)) { - nMetaTimeLen = dbv.cpbVal; - pMetaTime = (BYTE*)_alloca(dbv.cpbVal); - for (int i = 0; i < dbv.cpbVal; i++) - pMetaTime[i] = dbv.pbVal[dbv.cpbVal - i - 1]; - - db_free(&dbv); - } - - if (!getSetting(hContact, DBSETTING_SERVLIST_DATA, &dbv)) { // read additional server item data - nDataLen = dbv.cpbVal; - pData = (BYTE*)_alloca(nDataLen); - memcpy(pData, dbv.pbVal, nDataLen); - - db_free(&dbv); - } - - size_t nNickLen = mir_strlen(szNick); - size_t nNoteLen = mir_strlen(szNote); - - // Limit the strings - int bDataTooLong = FALSE; - if (nNickLen > MAX_SSI_TLV_NAME_SIZE) { - bDataTooLong = TRUE; - nNickLen = null_strcut(szNick, MAX_SSI_TLV_NAME_SIZE); - } - if (nNoteLen > MAX_SSI_TLV_COMMENT_SIZE) { - bDataTooLong = TRUE; - nNoteLen = null_strcut(szNote, MAX_SSI_TLV_COMMENT_SIZE); - } - if (bDataTooLong) { // Inform the user - /// TODO: do something with this for Manage Server-List dialog. - if (wAction != ICQ_LISTS_REMOVEFROMLIST) // do not report this when removing from list - icq_LogMessage(LOG_WARNING, LPGEN("The contact's information was too big and was truncated.")); - } - - // Build the packet - size_t wTLVlen = (nNickLen ? 4 + nNickLen : 0) + (nNoteLen ? 4 + nNoteLen : 0) + (bAuth ? 4 : 0) + nDataLen + (nMetaTokenLen ? 4 + nMetaTokenLen : 0) + (nMetaTimeLen ? 4 + nMetaTimeLen : 0); - - // Initialize our handy data buffer - icq_packet pBuffer; - pBuffer.wPlace = 0; - pBuffer.pData = (BYTE *)_alloca(wTLVlen); - pBuffer.wLen = (WORD)wTLVlen; - - if (nNickLen) - packTLV(&pBuffer, SSI_TLV_NAME, nNickLen, (LPBYTE)szNick); // Nickname TLV - - if (nNoteLen) - packTLV(&pBuffer, SSI_TLV_COMMENT, nNoteLen, (LPBYTE)szNote); // Comment TLV - - if (nMetaTokenLen) - packTLV(&pBuffer, SSI_TLV_METAINFO_TOKEN, nMetaTokenLen, pMetaToken); - - if (nMetaTimeLen) - packTLV(&pBuffer, SSI_TLV_METAINFO_TIME, nMetaTimeLen, pMetaTime); - - if (pData) - packBuffer(&pBuffer, pData, nDataLen); - - if (bAuth) // icq5 gives this as last TLV - packDWord(&pBuffer, 0x00660000); // "Still waiting for auth" TLV - - SAFE_FREE((void**)&szNick); - SAFE_FREE((void**)&szNote); - - return icq_sendServerItem(dwCookie, wAction, wGroupId, wContactId, strUID(dwUin, szUid), pBuffer.pData, wTLVlen, SSI_ITEM_BUDDY, dwOperation, dwTimeout, doubleObject); -} - -DWORD CIcqProto::icq_sendSimpleItem(DWORD dwCookie, WORD wAction, DWORD dwUin, char* szUID, WORD wGroupId, WORD wItemId, WORD wItemType, DWORD dwOperation, DWORD dwTimeout) -{ // for privacy items - return icq_sendServerItem(dwCookie, wAction, wGroupId, wItemId, strUID(dwUin, szUID), nullptr, 0, wItemType, dwOperation, dwTimeout, nullptr); -} - -DWORD CIcqProto::icq_sendServerGroup(DWORD dwCookie, WORD wAction, WORD wGroupId, const char *szName, void *pContent, int cbContent, DWORD dwOperationFlags) -{ - WORD wTLVlen; - icq_packet pBuffer; // I reuse the ICQ packet type as a generic buffer - // I should be ashamed! ;) - - if (mir_strlen(szName) == 0 && wGroupId != 0) { - debugLogA("Group upload failed (GroupName missing)."); - return 0; // without name we could not change the group - } - - // Calculate buffer size - wTLVlen = (cbContent ? 4 + cbContent : 0); - - // Initialize our handy data buffer - pBuffer.wPlace = 0; - pBuffer.pData = (BYTE *)_alloca(wTLVlen); - pBuffer.wLen = wTLVlen; - - if (wTLVlen) - packTLV(&pBuffer, SSI_TLV_SUBITEMS, cbContent, (LPBYTE)pContent); // Groups TLV - - return icq_sendServerItem(dwCookie, wAction, wGroupId, 0, szName, pBuffer.pData, wTLVlen, SSI_ITEM_GROUP, SSOP_GROUP_ACTION | dwOperationFlags, 400, nullptr); -} - -DWORD CIcqProto::icq_modifyServerPrivacyItem(MCONTACT hContact, DWORD dwUin, char *szUid, WORD wAction, DWORD dwOperation, WORD wItemId, WORD wType) -{ - cookie_servlist_action *ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action)); - DWORD dwCookie; - - if (ack) { - ack->dwAction = dwOperation; // remove privacy item - ack->hContact = hContact; - ack->wContactId = wItemId; - - dwCookie = AllocateCookie(CKT_SERVERLIST, wAction, hContact, ack); - } - else // cookie failed - return 0; - - return icq_sendSimpleItem(dwCookie, wAction, dwUin, szUid, 0, wItemId, wType, SSOP_ITEM_ACTION, 400); -} - -DWORD CIcqProto::icq_removeServerPrivacyItem(MCONTACT hContact, DWORD dwUin, char *szUid, WORD wItemId, WORD wType) -{ - return icq_modifyServerPrivacyItem(hContact, dwUin, szUid, ICQ_LISTS_REMOVEFROMLIST, SSA_PRIVACY_REMOVE, wItemId, wType); -} - -DWORD CIcqProto::icq_addServerPrivacyItem(MCONTACT hContact, DWORD dwUin, char *szUid, WORD wItemId, WORD wType) -{ - return icq_modifyServerPrivacyItem(hContact, dwUin, szUid, ICQ_LISTS_ADDTOLIST, SSA_PRIVACY_ADD, wItemId, wType); -} - -/***************************************** -* --- Contact DB Utilities --- -*/ - -/// TODO: do not check by plugin version, check by ServListStructures version! -int CIcqProto::IsServerGroupsDefined() -{ - int iRes = 1; - - if (getDword("Version", 0) < 0x00030608) { // group cache & linking data too old, flush, reload from server - char szModule[MAX_PATH]; - - // flush obsolete linking data - mir_snprintf(szModule, "%sGroups", m_szModuleName); - db_delete_module(0, szModule); - - iRes = 0; // no groups defined, or older version - } - // store our current version - setDword("Version", ICQ_PLUG_VERSION & 0x00FFFFFF); - - return iRes; -} - -void CIcqProto::FlushSrvGroupsCache() -{ - char szModule[MAX_PATH]; - mir_snprintf(szModule, "%sSrvGroups", m_szModuleName); - db_delete_module(0, szModule); -} - -// Look thru DB and collect all ContactIDs from a group -void* CIcqProto::collectBuddyGroup(WORD wGroupID, int *count) -{ - WORD* buf = nullptr; - int cnt = 0; - WORD wItemID; - - for (auto &hContact : AccContacts()) { - if (wGroupID == getWord(hContact, DBSETTING_SERVLIST_GROUP, 0)) { // add only buddys from specified group - wItemID = getWord(hContact, DBSETTING_SERVLIST_ID, 0); - - if (wItemID) { // valid ID, add - cnt++; - buf = (WORD*)SAFE_REALLOC(buf, cnt*sizeof(WORD)); - buf[cnt - 1] = wItemID; - if (!count) break; - } - } - } - - if (count) - *count = cnt << 1; // we return size in bytes - return buf; -} - -// Look thru DB and collect all GroupIDs -void* CIcqProto::collectGroups(int *count) -{ - WORD *buf = nullptr; - int cnt = 0; - int i; - WORD wGroupID; - - for (auto &hContact : AccContacts()) { - if (wGroupID = getWord(hContact, DBSETTING_SERVLIST_GROUP, 0)) { // add only valid IDs - for (i = 0; i < cnt; i++) // check for already added ids - if (buf[i] == wGroupID) - break; - - // not preset, add - if (i == cnt) { - cnt++; - buf = (WORD*)SAFE_REALLOC(buf, cnt*sizeof(WORD)); - buf[i] = wGroupID; - } - } - } - - *count = cnt << 1; - return buf; -} - -static int GroupLinksEnumProc(const char *szSetting, void *lParam) -{ - // check link target, add if match - if (db_get_w(0, ((char**)lParam)[2], szSetting, 0) == (WORD)((char**)lParam)[1]) { - char** block = (char**)SAFE_MALLOC(2 * sizeof(char*)); - block[1] = null_strdup(szSetting); - block[0] = ((char**)lParam)[0]; - ((char**)lParam)[0] = (char*)block; - } - return 0; -} - -void CIcqProto::removeGroupPathLinks(WORD wGroupID) -{ - // remove miranda grouppath links targeting to this groupid - char szModule[MAX_PATH]; - char* pars[3]; - - mir_snprintf(szModule, "%sGroups", m_szModuleName); - - pars[0] = nullptr; - pars[1] = (char*)wGroupID; - pars[2] = szModule; - - if (!db_enum_settings(NULL, &GroupLinksEnumProc, szModule, pars)) { // we found some links, remove them - char** list = (char**)pars[0]; - while (list) { - void* bet; - - db_unset(0, szModule, list[1]); - SAFE_FREE((void**)&list[1]); - bet = list; - list = (char**)list[0]; - SAFE_FREE((void**)&bet); - } - } -} - -char* CIcqProto::getServListGroupName(WORD wGroupID) -{ - char szModule[MAX_PATH]; - char szGroup[16]; - - if (!wGroupID) { - debugLogA("Warning: Cannot get group name (Group ID missing)!"); - return nullptr; - } - - mir_snprintf(szModule, "%sSrvGroups", m_szModuleName); - _itoa(wGroupID, szGroup, 0x10); - - if (!CheckServerID(wGroupID, 0)) { // check if valid id, if not give empty and remove - debugLogA("Removing group %u from cache...", wGroupID); - db_unset(0, szModule, szGroup); - return nullptr; - } - - return getSettingStringUtf(NULL, szModule, szGroup, nullptr); -} - -void CIcqProto::setServListGroupName(WORD wGroupID, const char *szGroupName) -{ - char szModule[MAX_PATH]; - char szGroup[16]; - - if (!wGroupID) { - debugLogA("Warning: Cannot set group name (Group ID missing)!"); - return; - } - - mir_snprintf(szModule, "%sSrvGroups", m_szModuleName); - _itoa(wGroupID, szGroup, 0x10); - - if (szGroupName) - db_set_utf(NULL, szModule, szGroup, szGroupName); - else { - db_unset(0, szModule, szGroup); - removeGroupPathLinks(wGroupID); - } -} - -WORD CIcqProto::getServListGroupLinkID(const char *szPath) -{ - char szModule[MAX_PATH]; - mir_snprintf(szModule, "%sGroups", m_szModuleName); - - WORD wGroupId = db_get_w(0, szModule, szPath, 0); - - if (wGroupId && !CheckServerID(wGroupId, 0)) { // known, check if still valid, if not remove - debugLogA("Removing group \"%s\" from cache...", szPath); - db_unset(0, szModule, szPath); - wGroupId = 0; - } - - return wGroupId; -} - -void CIcqProto::setServListGroupLinkID(const char *szPath, WORD wGroupID) -{ - char szModule[MAX_PATH]; - mir_snprintf(szModule, "%sGroups", m_szModuleName); - - if (wGroupID) - db_set_w(0, szModule, szPath, wGroupID); - else - db_unset(0, szModule, szPath); -} - -// determine if the specified clist group path exists -//!! this function is not thread-safe due to the use of cli->pfnGetGroupName() -int CIcqProto::getCListGroupExists(const char *szGroup) -{ - if (!szGroup) - return 0; - - size_t size = mir_strlen(szGroup) + 2; - wchar_t *tszGroup = (wchar_t*)_alloca(size * sizeof(wchar_t)); - - if (make_unicode_string_static(szGroup, tszGroup, size)) - for (int i = 1; TRUE; i++) { - wchar_t *tszGroupName = (wchar_t*)Clist_GroupGetName(i, nullptr); - if (!tszGroupName) - break; - - // we have found the group - if (!mir_wstrcmp(tszGroup, tszGroupName)) - return i; - } - - return 0; -} - - -int CIcqProto::moveContactToCListGroup(MCONTACT hContact, const char *szGroup) -{ - MGROUP hGroup = Clist_GroupCreate(0, ptrW(mir_utf8decodeW(szGroup))); - return Clist_ContactChangeGroup(hContact, hGroup); -} - - -// utility function which counts > on start of a server group name -static int countGroupNameLevel(const char *szGroupName) -{ - size_t nNameLen = mir_strlen(szGroupName); - - for (size_t i=0; i < nNameLen; i++) - if (szGroupName[i] != '>') - return (int)i; - - return -1; -} - -static int countCListGroupLevel(const char *szClistName) -{ - size_t nNameLen = mir_strlen(szClistName); - int level = 0; - - for (size_t i = 0; i < nNameLen; i++) - if (szClistName[i] == '\\') level++; - - return level; -} - -int CIcqProto::getServListGroupLevel(WORD wGroupId) -{ - char *szGroupName = getServListGroupName(wGroupId); - int cnt = -1; - - if (szGroupName) { // groupid is valid count group name level - if (m_bSsiSimpleGroups) - cnt = countCListGroupLevel(szGroupName); - else - cnt = countGroupNameLevel(szGroupName); - - SAFE_FREE((void**)&szGroupName); - } - - return cnt; -} - - -// demangle group path -char *CIcqProto::getServListGroupCListPath(WORD wGroupId) -{ - char *szGroup = nullptr; - - if (szGroup = getServListGroupName(wGroupId)) { // this groupid is valid - if (!m_bSsiSimpleGroups) - while (strstrnull(szGroup, "\\")) *strstrnull(szGroup, "\\") = '_'; // remove invalid char - - if (getServListGroupLinkID(szGroup) == wGroupId) { // this grouppath is known and is for this group, set user group - return szGroup; - } - else if (m_bSsiSimpleGroups) { // with simple groups it is mapped 1:1, give real serv-list group name - setServListGroupLinkID(szGroup, wGroupId); - return szGroup; - } - else { // advanced groups, determine group level - int nGroupLevel = getServListGroupLevel(wGroupId); - - if (nGroupLevel > 0) { // it is probably a sub-group locate parent group - WORD wParentGroupId = wGroupId; - int nParentGroupLevel; - - do { // we look for parent group at the correct level - wParentGroupId--; - nParentGroupLevel = getServListGroupLevel(wParentGroupId); - } - while ((nParentGroupLevel >= nGroupLevel) && (nParentGroupLevel != -1)); - - if (nParentGroupLevel == -1) { // that was not a sub-group, it was just a group starting with > - setServListGroupLinkID(szGroup, wGroupId); - return szGroup; - } - - // recursively determine parent group clist path - char *szParentGroup = getServListGroupCListPath(wParentGroupId); - - /// FIXME: properly handle ~N suffixes - szParentGroup = (char*)SAFE_REALLOC(szParentGroup, mir_strlen(szGroup) + mir_strlen(szParentGroup) + 2); - mir_strcat(szParentGroup, "\\"); - mir_strcat(szParentGroup, (char*)szGroup + nGroupLevel); - - SAFE_FREE((void**)&szGroup); - szGroup = szParentGroup; - - if (getServListGroupLinkID(szGroup) == wGroupId) // known path, give - return szGroup; - } - - setServListGroupLinkID(szGroup, wGroupId); - return szGroup; - } - } - return nullptr; -} - - -static int SrvGroupNamesEnumProc(const char *szSetting, void *lParam) -{ - // check server-group cache item - const char **params = (const char**)lParam; - CIcqProto *ppro = (CIcqProto*)params[0]; - char *szGroupName = ppro->getSettingStringUtf(NULL, params[3], szSetting, nullptr); - - if (!mir_strcmp(szGroupName, params[2])) - params[1] = szSetting; // do not need the real value, just arbitrary non-NULL - - SAFE_FREE(&szGroupName); - return 0; -} - -char* CIcqProto::getServListUniqueGroupName(const char *szGroupName, int bAlloced) -{ - // enum ICQSrvGroups and create unique name if neccessary - char szModule[MAX_PATH]; - char *pars[4]; - int uniqueID = 1; - char *szGroupNameBase = (char*)szGroupName; - char *szNewGroupName = nullptr; - - if (!bAlloced) - szGroupNameBase = null_strdup(szGroupName); - null_strcut(szGroupNameBase, m_wServerListRecordNameMaxLength); - - mir_snprintf(szModule, "%sSrvGroups", m_szModuleName); - - do { - pars[0] = (char*)this; - pars[1] = nullptr; - pars[2] = szNewGroupName ? szNewGroupName : szGroupNameBase; - pars[3] = szModule; - db_enum_settings(NULL, &SrvGroupNamesEnumProc, szModule, pars); - - if (pars[1]) { // the groupname already exists, create another - SAFE_FREE((void**)&szNewGroupName); - - char szUnique[10]; - _itoa(uniqueID++, szUnique, 10); - null_strcut(szGroupNameBase, m_wServerListRecordNameMaxLength - mir_strlen(szUnique) - 1); - szNewGroupName = (char*)SAFE_MALLOC(mir_strlen(szUnique) + mir_strlen(szGroupNameBase) + 2); - if (szNewGroupName) { - mir_strcpy(szNewGroupName, szGroupNameBase); - mir_strcat(szNewGroupName, "~"); - mir_strcat(szNewGroupName, szUnique); - } - } - } - while (pars[1] && szNewGroupName); - - if (szNewGroupName) { - SAFE_FREE(&szGroupNameBase); - return szNewGroupName; - } - if (szGroupName != szGroupNameBase) { - SAFE_FREE(&szGroupNameBase); - return (char*)szGroupName; - } - return szGroupNameBase; -} - -// this is the second part of recursive event-driven procedure -int CIcqProto::servlistCreateGroup_gotParentGroup(const char *szGroup, WORD wGroupID, LPARAM param, int nResult) -{ - cookie_servlist_action* clue = (cookie_servlist_action*)param; - char *szSubGroupName = clue->szGroupName; - char *szSubGroup; - int wSubGroupLevel = -1; - WORD wSubGroupID; - - SAFE_FREE((void**)&clue); - - if (nResult == PENDING_RESULT_PURGE) // only cleanup - return CALLBACK_RESULT_CONTINUE; - - szSubGroup = (char*)SAFE_MALLOC(mir_strlen(szGroup) + mir_strlen(szSubGroupName) + 2); - if (szSubGroup) { - mir_strcpy(szSubGroup, szGroup); - mir_strcat(szSubGroup, "\\"); - mir_strcat(szSubGroup, szSubGroupName); - } - - if (nResult == PENDING_RESULT_SUCCESS) // if we got an id count level - wSubGroupLevel = getServListGroupLevel(wGroupID); - - if (wSubGroupLevel == -1) { // something went wrong, give the id and go away - servlistPendingRemoveGroup(szSubGroup, wGroupID, PENDING_RESULT_FAILED); - - SAFE_FREE((void**)&szSubGroupName); - SAFE_FREE((void**)&szSubGroup); - return CALLBACK_RESULT_CONTINUE; - } - wSubGroupLevel++; // we are a sub-group - wSubGroupID = wGroupID + 1; - - // check if on that id is not group of the same or greater level, if yes, try next - while (CheckServerID(wSubGroupID, 0) && (getServListGroupLevel(wSubGroupID) >= wSubGroupLevel)) - wSubGroupID++; - - if (!CheckServerID(wSubGroupID, 0)) { // the next id is free, so create our group with that id - cookie_servlist_action *ack; - DWORD dwCookie; - char *szSubGroupItem = (char*)SAFE_MALLOC(mir_strlen(szSubGroupName) + wSubGroupLevel + 1); - - if (szSubGroupItem) { - int i; - - for (i = 0; i < wSubGroupLevel; i++) - szSubGroupItem[i] = '>'; - - mir_strcpy(szSubGroupItem + wSubGroupLevel, szSubGroupName); - szSubGroupItem[mir_strlen(szSubGroupName) + wSubGroupLevel] = '\0'; - SAFE_FREE((void**)&szSubGroupName); - // check and create unique group name (Miranda does allow more subgroups with the same name!) - szSubGroupItem = getServListUniqueGroupName(szSubGroupItem, TRUE); - - if (ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action))) { // we have cookie good, go on - debugLogA("Server-List: Creating sub-group \"%s\", parent group \"%s\".", szSubGroupItem, szGroup); - - ReserveServerID(wSubGroupID, SSIT_GROUP, 0); - - ack->wGroupId = wSubGroupID; - ack->szGroupName = szSubGroupItem; // we need that name - ack->szGroup = szSubGroup; - ack->dwAction = SSA_GROUP_ADD; - dwCookie = AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_ADDTOLIST, 0, ack); - - icq_sendServerGroup(dwCookie, ICQ_LISTS_ADDTOLIST, ack->wGroupId, szSubGroupItem, nullptr, 0, SSOF_BEGIN_OPERATION); - return CALLBACK_RESULT_CONTINUE; - } - SAFE_FREE((void**)&szSubGroupItem); - } - } - // we failed to create sub-group give parent groupid - icq_LogMessage(LOG_ERROR, LPGEN("Failed to create the correct sub-group, the using closest parent group.")); - - servlistPendingRemoveGroup(szSubGroup, wGroupID, PENDING_RESULT_FAILED); - - SAFE_FREE((void**)&szSubGroupName); - SAFE_FREE((void**)&szSubGroup); - return CALLBACK_RESULT_CONTINUE; -} - - -int CIcqProto::servlistCreateGroup_Ready(const char *szGroup, WORD groupID, LPARAM, int nResult) -{ - WORD wGroupID = 0; - - if (nResult == PENDING_RESULT_PURGE) - return CALLBACK_RESULT_CONTINUE; - - if (wGroupID = getServListGroupLinkID(szGroup)) { // the path is known, continue the process - servlistPendingRemoveGroup(szGroup, wGroupID, PENDING_RESULT_SUCCESS); - return CALLBACK_RESULT_CONTINUE; - } - - if (!strstrnull(szGroup, "\\") || m_bSsiSimpleGroups) { // a root group can be simply created without problems; simple groups are mapped directly - cookie_servlist_action* ack; - DWORD dwCookie; - - if (ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action))) { // we have cookie good, go on - debugLogA("Server-List: Creating root group \"%s\".", szGroup); - - ack->wGroupId = GenerateServerID(SSIT_GROUP, 0); - ack->szGroup = null_strdup(szGroup); // we need that name - // check if the groupname is unique - just to be sure, Miranda should handle that! - ack->szGroupName = getServListUniqueGroupName(ack->szGroup, FALSE); - ack->dwAction = SSA_GROUP_ADD; - dwCookie = AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_ADDTOLIST, 0, ack); - - icq_sendServerGroup(dwCookie, ICQ_LISTS_ADDTOLIST, ack->wGroupId, ack->szGroup, nullptr, 0, SSOF_BEGIN_OPERATION); - - return CALLBACK_RESULT_POSTPONE; - } - } - else { // this is a sub-group - char *szSub = null_strdup(szGroup); // create subgroup, recursive, event-driven, possibly relocate - char *szLast = strrchr(szSub, '\\') + 1; - szLast[-1] = '\0'; - - // make parent group id - cookie_servlist_action *ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action)); - if (ack) { - ack->szGroupName = null_strdup(szLast); // groupname - servlistCreateGroup(szSub, (LPARAM)ack, &CIcqProto::servlistCreateGroup_gotParentGroup); - SAFE_FREE((void**)&szSub); - - return CALLBACK_RESULT_POSTPONE; - } - - SAFE_FREE((void**)&szSub); - } - - servlistPendingRemoveGroup(szGroup, groupID, PENDING_RESULT_FAILED); - return CALLBACK_RESULT_CONTINUE; -} - -// create group with this path, a bit complex task -// this supposes that all server groups are known -void CIcqProto::servlistCreateGroup(const char *szGroupPath, LPARAM param, PENDING_GROUP_CALLBACK callback) -{ - char *szGroup = (char*)szGroupPath; - - if (!mir_strlen(szGroup)) - szGroup = DEFAULT_SS_GROUP; - - servlistPendingAddGroup(szGroup, 0, 0, &CIcqProto::servlistCreateGroup_Ready, TRUE, param, callback); -} - -/***************************************** -* -* --- Server-List Operations --- -* -*/ - -int CIcqProto::servlistAddContact_gotGroup(const char*, WORD wGroupID, LPARAM lParam, int nResult) -{ - cookie_servlist_action* ack = (cookie_servlist_action*)lParam; - if (ack) - SAFE_FREE(&ack->szGroup); - - if (nResult == PENDING_RESULT_PURGE) { // only cleanup - SAFE_FREE((void**)&ack); - return CALLBACK_RESULT_CONTINUE; - } - - if (!ack || !wGroupID) { // something went wrong - if (ack) - servlistPendingRemoveContact(ack->hContact, 0, wGroupID, PENDING_RESULT_FAILED); - SAFE_FREE((void**)&ack); - return CALLBACK_RESULT_CONTINUE; - } - - WORD wItemID = getWord(ack->hContact, DBSETTING_SERVLIST_ID, 0); - if (wItemID) { - // Only add the contact if it doesnt already have an ID - servlistPendingRemoveContact(ack->hContact, wItemID, wGroupID, PENDING_RESULT_SUCCESS); - debugLogA("Failed to add contact to server side list (%s)", "already there"); - SAFE_FREE((void**)&ack); - return CALLBACK_RESULT_CONTINUE; - } - - wItemID = GenerateServerID(SSIT_ITEM, 0); - - ack->dwAction = SSA_CONTACT_ADD; - ack->wGroupId = wGroupID; - ack->wContactId = wItemID; - - DWORD dwCookie = AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_ADDTOLIST, ack->hContact, ack); - - icq_sendServerContact(ack->hContact, dwCookie, ICQ_LISTS_ADDTOLIST, wGroupID, wItemID, SSOP_ITEM_ACTION | SSOF_CONTACT | SSOF_BEGIN_OPERATION, 400, nullptr); - - return CALLBACK_RESULT_CONTINUE; -} - -// Need to be called when Pending Contact is active -int CIcqProto::servlistAddContact_Ready(MCONTACT hContact, WORD, WORD, LPARAM lParam, int nResult) -{ - cookie_servlist_action* ack = (cookie_servlist_action*)lParam; - - if (nResult == PENDING_RESULT_PURGE) { // removing obsolete items, just free the memory - SAFE_FREE((void**)&ack->szGroup); - SAFE_FREE((void**)&ack); - return CALLBACK_RESULT_CONTINUE; - } - - WORD wItemID = getWord(ack->hContact, DBSETTING_SERVLIST_ID, 0); - - if (wItemID) { // Only add the contact if it doesn't already have an ID - servlistPendingRemoveContact(ack->hContact, wItemID, getWord(hContact, DBSETTING_SERVLIST_GROUP, 0), PENDING_RESULT_SUCCESS); - debugLogA("Failed to add contact to server side list (%s)", "already there"); - SAFE_FREE((void**)&ack->szGroup); - SAFE_FREE((void**)&ack); - return CALLBACK_RESULT_CONTINUE; - } - - // obtain a correct groupid first - servlistCreateGroup(ack->szGroup, lParam, &CIcqProto::servlistAddContact_gotGroup); - - return CALLBACK_RESULT_POSTPONE; -} - -// Called when contact should be added to server list, if group does not exist, create one -void CIcqProto::servlistAddContact(MCONTACT hContact, const char *pszGroup) -{ - // Get UID - DWORD dwUin; - uid_str szUid; - if (getContactUid(hContact, &dwUin, &szUid)) { // Could not do anything without uid - debugLogA("Failed to add contact to server side list (%s)", "no UID"); - return; - } - - cookie_servlist_action* ack; - if (!(ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action)))) { // Could not do anything without cookie - debugLogA("Failed to add contact to server side list (%s)", "malloc failed"); - return; - } - - ack->hContact = hContact; - ack->szGroup = null_strdup(pszGroup); - // call thru pending operations - makes sure the contact is ready to be added - servlistPendingAddContact(hContact, 0, 0, (LPARAM)ack, &CIcqProto::servlistAddContact_Ready, TRUE); -} - -int CIcqProto::servlistRemoveContact_Ready(MCONTACT hContact, WORD contactID, WORD groupID, LPARAM lParam, int nResult) -{ - WORD wGroupID; - WORD wItemID; - cookie_servlist_action* ack = (cookie_servlist_action*)lParam; - DWORD dwCookie; - - if (nResult == PENDING_RESULT_PURGE) { - SAFE_FREE((void**)&ack); - return CALLBACK_RESULT_CONTINUE; - } - - // Get the contact's group ID - if (!(wGroupID = getWord(hContact, DBSETTING_SERVLIST_GROUP, 0))) { // Could not find a usable group ID - servlistPendingRemoveContact(hContact, contactID, groupID, PENDING_RESULT_FAILED); - - debugLogA("Failed to remove contact from server side list (%s)", "no group ID"); - SAFE_FREE((void**)&ack); - return CALLBACK_RESULT_CONTINUE; - } - - // Get the contact's item ID - if (!(wItemID = getWord(hContact, DBSETTING_SERVLIST_ID, 0))) { // Could not find usable item ID - servlistPendingRemoveContact(hContact, contactID, wGroupID, PENDING_RESULT_FAILED); - - debugLogA("Failed to remove contact from server side list (%s)", "no item ID"); - SAFE_FREE((void**)&ack); - return CALLBACK_RESULT_CONTINUE; - } - - ack->dwAction = SSA_CONTACT_REMOVE; - ack->hContact = hContact; - ack->wGroupId = wGroupID; - ack->wContactId = wItemID; - - dwCookie = AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_REMOVEFROMLIST, hContact, ack); - - icq_sendServerContact(hContact, dwCookie, ICQ_LISTS_REMOVEFROMLIST, wGroupID, wItemID, SSOP_ITEM_ACTION | SSOF_CONTACT | SSOF_BEGIN_OPERATION, 400, nullptr); - - return CALLBACK_RESULT_POSTPONE; -} - -// Called when contact should be removed from server list, remove group if it remain empty -void CIcqProto::servlistRemoveContact(MCONTACT hContact) -{ - // Get UID - DWORD dwUin; - uid_str szUid; - if (getContactUid(hContact, &dwUin, &szUid)) { - // Could not do anything without uid - debugLogA("Failed to remove contact from server side list (%s)", "no UID"); - return; - } - - cookie_servlist_action* ack; - if (!(ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action)))) { // Could not do anything without cookie - debugLogA("Failed to remove contact from server side list (%s)", "malloc failed"); - return; - } - - ack->hContact = hContact; - // call thru pending operations - makes sure the contact is ready to be removed - servlistPendingAddContact(hContact, 0, 0, (LPARAM)ack, &CIcqProto::servlistRemoveContact_Ready, TRUE); -} - - -int CIcqProto::servlistMoveContact_gotTargetGroup(const char *szGroup, WORD wNewGroupID, LPARAM lParam, int nResult) -{ - cookie_servlist_action *ack = (cookie_servlist_action*)lParam; - if (ack) - SAFE_FREE(&ack->szGroup); - - if (nResult == PENDING_RESULT_PURGE) { // removing obsolete items, just free the memory - SAFE_FREE((void**)&ack); - return CALLBACK_RESULT_CONTINUE; - } - - if (!ack || !wNewGroupID || !ack->hContact) { // something went wrong - if (ack) - servlistPendingRemoveContact(ack->hContact, 0, 0, PENDING_RESULT_FAILED); - SAFE_FREE((void**)&ack); - return CALLBACK_RESULT_CONTINUE; - } - - WORD wItemID = getWord(ack->hContact, DBSETTING_SERVLIST_ID, 0); - WORD wGroupID = getWord(ack->hContact, DBSETTING_SERVLIST_GROUP, 0); - - if (!wItemID) { // We have no ID, so try to simply add the contact to serv-list - debugLogA("Unable to move contact (no ItemID) -> trying to add"); - // we know the GroupID, so directly call add - return servlistAddContact_gotGroup(szGroup, wNewGroupID, lParam, nResult); - } - - if (wGroupID == wNewGroupID) { // Only move the contact if it had different GroupID - servlistPendingRemoveContact(ack->hContact, wItemID, wNewGroupID, PENDING_RESULT_SUCCESS); - debugLogA("Contact not moved to group on server side list (same Group)"); - return CALLBACK_RESULT_CONTINUE; - } - - ack->szGroupName = nullptr; - ack->dwAction = SSA_CONTACT_SET_GROUP; - ack->wGroupId = wGroupID; - ack->wContactId = wItemID; - ack->wNewContactId = GenerateServerID(SSIT_ITEM, 0); // icq5 recreates also this, imitate - ack->wNewGroupId = wNewGroupID; - ack->lParam = 0; // we use this as a sign - - DWORD dwCookie = AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_REMOVEFROMLIST, ack->hContact, ack); - DWORD dwCookie2 = AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_ADDTOLIST, ack->hContact, ack); - { - // imitate icq5, previously here was different order, but AOL changed and it ceased to work - void *doubleObject = nullptr; - - icq_sendServerContact(ack->hContact, dwCookie2, ICQ_LISTS_ADDTOLIST, wNewGroupID, ack->wNewContactId, SSO_CONTACT_SETGROUP | SSOF_BEGIN_OPERATION, 500, &doubleObject); - icq_sendServerContact(ack->hContact, dwCookie, ICQ_LISTS_REMOVEFROMLIST, wGroupID, wItemID, SSO_CONTACT_SETGROUP | SSOF_BEGIN_OPERATION, 500, &doubleObject); - } - return CALLBACK_RESULT_CONTINUE; -} - -int CIcqProto::servlistMoveContact_Ready(MCONTACT, WORD contactID, WORD groupID, LPARAM lParam, int nResult) -{ - cookie_servlist_action *ack = (cookie_servlist_action*)lParam; - - if (nResult == PENDING_RESULT_PURGE) { // removing obsolete items, just free the memory - SAFE_FREE(&ack->szGroup); - SAFE_FREE((void**)&ack); - return CALLBACK_RESULT_CONTINUE; - } - - WORD wItemID = getWord(ack->hContact, DBSETTING_SERVLIST_ID, 0); - WORD wGroupID = getWord(ack->hContact, DBSETTING_SERVLIST_GROUP, 0); - - if (!wGroupID && wItemID) { // Only move the contact if it had an GroupID - servlistPendingRemoveContact(ack->hContact, contactID, groupID, PENDING_RESULT_FAILED); - - debugLogA("Failed to move contact to group on server side list (%s)", "no Group"); - SAFE_FREE(&ack->szGroup); - SAFE_FREE((void**)&ack); - return CALLBACK_RESULT_CONTINUE; - } - - // obtain a correct target groupid first - servlistCreateGroup(ack->szGroup, lParam, &CIcqProto::servlistMoveContact_gotTargetGroup); - return CALLBACK_RESULT_POSTPONE; -} - -// Called when contact should be moved from one group to another, create new, remove empty -void CIcqProto::servlistMoveContact(MCONTACT hContact, const char *pszNewGroup) -{ - if (!hContact) return; // we do not move us, caused our uin was wrongly added to list - - // Get UID - DWORD dwUin; - uid_str szUid; - if (getContactUid(hContact, &dwUin, &szUid)) { // Could not do anything without uin - debugLogA("Failed to move contact to group on server side list (%s)", "no UID"); - return; - } - - if ((pszNewGroup != nullptr) && (pszNewGroup[0] != '\0') && !getCListGroupExists(pszNewGroup)) { // the contact moved to non existing group, do not do anything: MetaContact hack - debugLogA("Contact not moved - probably hiding by MetaContacts."); - return; - } - - if (!getWord(hContact, DBSETTING_SERVLIST_ID, 0)) /// FIXME:::: this should be in _ready - { // the contact is not stored on the server, check if we should try to add - if (!getByte("ServerAddRemove", DEFAULT_SS_ADDSERVER) || - db_get_b(hContact, "CList", "Hidden", 0)) - return; - } - cookie_servlist_action *ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action)); - - if (!ack) { // Could not do anything without cookie - debugLogA("Failed to add contact to server side list (%s)", "malloc failed"); - return; - } - else { - ack->hContact = hContact; - ack->szGroup = null_strdup(pszNewGroup); - // call thru pending operations - makes sure the contact is ready to be moved - servlistPendingAddContact(hContact, 0, 0, (LPARAM)ack, &CIcqProto::servlistMoveContact_Ready, TRUE); - return; - } -} - - -int CIcqProto::servlistUpdateContact_Ready(MCONTACT hContact, WORD contactID, WORD groupID, LPARAM lParam, int nResult) -{ - cookie_servlist_action *ack = (cookie_servlist_action*)lParam; - - if (nResult == PENDING_RESULT_PURGE) { // removing obsolete items, just free the memory - SAFE_FREE((void**)&ack); - return CALLBACK_RESULT_CONTINUE; - } - WORD wItemID; - WORD wGroupID; - - // Get the contact's group ID - if (!(wGroupID = getWord(hContact, DBSETTING_SERVLIST_GROUP, 0))) { - servlistPendingRemoveContact(hContact, contactID, groupID, PENDING_RESULT_FAILED); - // Could not find a usable group ID - debugLogA("Failed to update contact's details on server side list (%s)", "no group ID"); - SAFE_FREE((void**)&ack); - return CALLBACK_RESULT_CONTINUE; - } - - // Get the contact's item ID - if (!(wItemID = getWord(hContact, DBSETTING_SERVLIST_ID, 0))) { - servlistPendingRemoveContact(hContact, contactID, wGroupID, PENDING_RESULT_FAILED); - // Could not find usable item ID - debugLogA("Failed to update contact's details on server side list (%s)", "no item ID"); - SAFE_FREE((void**)&ack); - return CALLBACK_RESULT_CONTINUE; - } - - ack->dwAction = SSA_CONTACT_UPDATE; - ack->wContactId = wItemID; - ack->wGroupId = wGroupID; - ack->hContact = hContact; - - DWORD dwCookie = AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_UPDATEGROUP, hContact, ack); - - // There is no need to send ICQ_LISTS_CLI_MODIFYSTART or - // ICQ_LISTS_CLI_MODIFYEND when just changing nick name - icq_sendServerContact(hContact, dwCookie, ICQ_LISTS_UPDATEGROUP, wGroupID, wItemID, SSOP_ITEM_ACTION | SSOF_CONTACT, 400, nullptr); - - return CALLBACK_RESULT_POSTPONE; -} - - -// Is called when a contact' details has been changed locally to update -// the server side details. -void CIcqProto::servlistUpdateContact(MCONTACT hContact) -{ - // Get UID - DWORD dwUin; - uid_str szUid; - if (getContactUid(hContact, &dwUin, &szUid)) { - // Could not set nickname on server without uid - debugLogA("Failed to update contact's details on server side list (%s)", "no UID"); - return; - } - - cookie_servlist_action *ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action)); - if (!ack) { - // Could not allocate cookie - use old fake - debugLogA("Failed to update contact's details on server side list (%s)", "malloc failed"); - return; - } - - ack->hContact = hContact; - // call thru pending operations - makes sure the contact is ready to be updated - servlistPendingAddContact(hContact, 0, 0, (LPARAM)ack, &CIcqProto::servlistUpdateContact_Ready, TRUE); -} - -int CIcqProto::servlistRenameGroup_Ready(const char *szGroup, WORD wGroupID, LPARAM lParam, int nResult) -{ - cookie_servlist_action *ack = (cookie_servlist_action*)lParam; - - if (nResult == PENDING_RESULT_PURGE) { // only cleanup - if (ack) - SAFE_FREE(&ack->szGroupName); - SAFE_FREE((void**)&ack); - return CALLBACK_RESULT_CONTINUE; - } - - if (!ack || !wGroupID) { // something went wrong - servlistPendingRemoveGroup(szGroup, wGroupID, PENDING_RESULT_FAILED); - - if (ack) SAFE_FREE(&ack->szGroupName); - SAFE_FREE((void**)&ack); - return CALLBACK_RESULT_CONTINUE; - } - - void *groupData; - int groupSize; - if (groupData = collectBuddyGroup(wGroupID, &groupSize)) { - ack->dwAction = SSA_GROUP_RENAME; - ack->wGroupId = wGroupID; - ack->szGroup = null_strdup(szGroup); // we need this name - // check if the new name is unique, create unique groupname if necessary - ack->szGroupName = getServListUniqueGroupName(ack->szGroupName, TRUE); - - DWORD dwCookie = AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_UPDATEGROUP, 0, ack); - - icq_sendServerGroup(dwCookie, ICQ_LISTS_UPDATEGROUP, wGroupID, ack->szGroupName, groupData, groupSize, 0); - SAFE_FREE(&groupData); - } - return CALLBACK_RESULT_POSTPONE; -} - - -void CIcqProto::servlistRenameGroup(char *szGroup, WORD wGroupId, char *szNewGroup) -{ - char *szNewGroupName; - int nGroupLevel = getServListGroupLevel(wGroupId); - - if (nGroupLevel == -1) return; // we failed to prepare group - - if (!m_bSsiSimpleGroups) { - char *szGroupName = szGroup; - int i = nGroupLevel; - while (i) { // find correct part of grouppath - szGroupName = strstrnull(szGroupName, "\\"); - if (!szGroupName) return; // failed to get correct part of the grouppath - szGroupName++; - i--; - } - szNewGroupName = szNewGroup; - i = nGroupLevel; - while (i) { // find correct part of new grouppath - szNewGroupName = strstrnull(szNewGroupName, "\\"); - if (!szNewGroupName) return; // failed to get correct part of the new grouppath - szNewGroupName++; - i--; - } - // truncate possible sub-groups - char *szLast = strstrnull(szGroupName, "\\"); - if (szLast) - szLast[0] = '\0'; - szLast = strstrnull(szNewGroupName, "\\"); - if (szLast) - szLast[0] = '\0'; - - // this group was not changed, nothing to rename - if (!mir_strcmp(szGroupName, szNewGroupName)) return; - - szGroupName = szNewGroupName; - szNewGroupName = (char*)SAFE_MALLOC(mir_strlen(szGroupName) + 1 + nGroupLevel); - if (!szNewGroupName) return; // Failure - - for (i = 0; i < nGroupLevel; i++) { // create level prefix - szNewGroupName[i] = '>'; - } - mir_strcat(szNewGroupName, szGroupName); - } - else // simple groups do not require any conversion - szNewGroupName = null_strdup(szNewGroup); - - cookie_servlist_action* ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action)); - if (!ack) { // cookie failed - debugLogA("Error: Failed to allocate cookie"); - - SAFE_FREE(&szNewGroupName); - return; - } - // store new group name for future use - ack->szGroupName = szNewGroupName; - // call thru pending operations - makes sure the group is ready for rename - servlistPendingAddGroup(szGroup, wGroupId, (LPARAM)ack, &CIcqProto::servlistRenameGroup_Ready, TRUE); -} - -int CIcqProto::servlistRemoveGroup_Ready(const char *szGroup, WORD groupID, LPARAM lParam, int nResult) -{ - cookie_servlist_action *ack = (cookie_servlist_action*)lParam; - - if (nResult == PENDING_RESULT_PURGE) { // only cleanup - SAFE_FREE((void**)&ack); - return CALLBACK_RESULT_CONTINUE; - } - WORD wGroupID = getServListGroupLinkID(szGroup); - char *szGroupName; - - if (wGroupID && (szGroupName = getServListGroupName(wGroupID))) { // the group is valid, check if it is empty - void *groupData = collectBuddyGroup(wGroupID, nullptr); - - if (groupData) { // the group is not empty, cannot delete - SAFE_FREE(&groupData); - SAFE_FREE(&szGroupName); - // end operation - servlistPendingRemoveGroup(szGroup, wGroupID, PENDING_RESULT_SUCCESS); - // cleanup - SAFE_FREE((void**)&ack); - return CALLBACK_RESULT_CONTINUE; - } - - if (!CheckServerID((WORD)(wGroupID + 1), 0) || getServListGroupLevel((WORD)(wGroupID + 1)) == 0) { // is next id an sub-group, if yes, we cannot delete this group - ack->dwAction = SSA_GROUP_REMOVE; - ack->wContactId = 0; - ack->wGroupId = wGroupID; - ack->hContact = NULL; - ack->szGroup = null_strdup(szGroup); // we need that name - ack->szGroupName = szGroupName; - DWORD dwCookie = AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_REMOVEFROMLIST, 0, ack); - - icq_sendServerGroup(dwCookie, ICQ_LISTS_REMOVEFROMLIST, ack->wGroupId, ack->szGroupName, nullptr, 0, 0); - } - return CALLBACK_RESULT_POSTPONE; - } - // end operation - servlistPendingRemoveGroup(szGroup, groupID, PENDING_RESULT_SUCCESS); - // cleanup - SAFE_FREE((void**)&ack); - return CALLBACK_RESULT_CONTINUE; -} - - -void CIcqProto::servlistRemoveGroup(const char *szGroup, WORD wGroupId) -{ - if (!szGroup) return; - - cookie_servlist_action *ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action)); - if (!ack) { // cookie failed - debugLogA("Error: Failed to allocate cookie"); - return; - } - - // call thru pending operations - makes sure the group is ready for removal - servlistPendingAddGroup(szGroup, wGroupId, (LPARAM)ack, &CIcqProto::servlistRemoveGroup_Ready, TRUE); -} - -void CIcqProto::resetServContactAuthState(MCONTACT hContact) -{ - WORD wContactId = getWord(hContact, DBSETTING_SERVLIST_ID, 0); - WORD wGroupId = getWord(hContact, DBSETTING_SERVLIST_GROUP, 0); - - if (wContactId && wGroupId) { - cookie_servlist_action *ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action)); - if (ack) { // we have cookie good, go on - ack->hContact = hContact; - ack->wContactId = wContactId; - ack->wGroupId = wGroupId; - ack->dwAction = SSA_CONTACT_FIX_AUTH; - - DWORD dwCookie = AllocateCookie(CKT_SERVERLIST, 0, hContact, ack); - - { - void *doubleObject = nullptr; - - icq_sendServerContact(hContact, dwCookie, ICQ_LISTS_REMOVEFROMLIST, wGroupId, wContactId, SSO_CONTACT_FIXAUTH | SSOF_BEGIN_OPERATION | SSOF_END_OPERATION, 200, &doubleObject); - delSetting(hContact, DBSETTING_METAINFO_TOKEN); - delSetting(hContact, DBSETTING_METAINFO_TIME); - delSetting(hContact, DBSETTING_SERVLIST_DATA); - icq_sendServerContact(hContact, dwCookie, ICQ_LISTS_ADDTOLIST, wGroupId, wContactId, SSO_CONTACT_FIXAUTH | SSOF_BEGIN_OPERATION | SSOF_END_OPERATION, 200, &doubleObject); - } - } - else debugLogA("Error: Failed to allocate cookie"); - } -} - -/***************************************** -* -* --- Miranda Contactlist Hooks --- -* -*/ - -int CIcqProto::ServListDbSettingChanged(WPARAM hContact, LPARAM lParam) -{ - DBCONTACTWRITESETTING* cws = (DBCONTACTWRITESETTING*)lParam; - - // TODO: Queue changes that occur while offline - if (!icqOnline() || !m_bSsiEnabled || bIsSyncingCL) - return 0; - - if (!strcmp(cws->szModule, "CList")) { - // Has contact been renamed? - if (!strcmp(cws->szSetting, "MyHandle") && getByte("StoreServerDetails", DEFAULT_SS_STORE)) - servlistUpdateContact(hContact); // Update contact's details in server-list - - // Has contact been moved to another group? - if (!strcmp(cws->szSetting, "Group") && getByte("StoreServerDetails", DEFAULT_SS_STORE)) { - char* szNewGroup = getContactCListGroup(hContact); // Read group from DB - SAFE_FREE(&szNewGroup); - } - } - else if (!strcmp(cws->szModule, "UserInfo")) { - // Update contact's details in server-list - if (!strcmp(cws->szSetting, "MyNotes") && getByte("StoreServerDetails", DEFAULT_SS_STORE)) - servlistUpdateContact(hContact); - } - - return 0; -} - - -void CIcqProto::OnContactDeleted(MCONTACT hContact) -{ - DeleteFromContactsCache(hContact); - - if (!icqOnline() && m_bSsiEnabled) - // contact was deleted only locally - retrieve full list on next connect - setWord(hContact, "SrvRecordCount", 0); - - if (!icqOnline() || !m_bSsiEnabled) - return; - - // we need all server contacts on local buddy list - DWORD dwUIN; - uid_str szUID; - if (getContactUid(hContact, &dwUIN, &szUID)) - return; - - WORD wContactID = getWord(hContact, DBSETTING_SERVLIST_ID, 0); - WORD wGroupID = getWord(hContact, DBSETTING_SERVLIST_GROUP, 0); - WORD wVisibleID = getWord(hContact, DBSETTING_SERVLIST_PERMIT, 0); - WORD wInvisibleID = getWord(hContact, DBSETTING_SERVLIST_DENY, 0); - WORD wIgnoreID = getWord(hContact, DBSETTING_SERVLIST_IGNORE, 0); - - // Remove from queue for user details request - icq_DequeueUser(dwUIN); - - // Close all opened peer connections - CloseContactDirectConns(hContact); - - if ((wGroupID && wContactID) || wVisibleID || wInvisibleID || wIgnoreID) { - if (wContactID) // delete contact from server - servlistRemoveContact(hContact); - - if (wVisibleID) // detete permit record - icq_removeServerPrivacyItem(hContact, dwUIN, szUID, wVisibleID, SSI_ITEM_PERMIT); - - if (wInvisibleID) // delete deny record - icq_removeServerPrivacyItem(hContact, dwUIN, szUID, wInvisibleID, SSI_ITEM_DENY); - - if (wIgnoreID) // delete ignore record - icq_removeServerPrivacyItem(hContact, dwUIN, szUID, wIgnoreID, SSI_ITEM_IGNORE); - } -} - - -int CIcqProto::ServListCListGroupChange(WPARAM hContact, LPARAM lParam) -{ - CLISTGROUPCHANGE *grpchg = (CLISTGROUPCHANGE*)lParam; - - if (!icqOnline() || !m_bSsiEnabled || bIsSyncingCL) - return 0; - - // only change server-list if it is allowed - if (!getByte("StoreServerDetails", DEFAULT_SS_STORE)) - return 0; - - if (hContact == NULL) { // change made to group - if (grpchg->pszNewName == nullptr && grpchg->pszOldName != nullptr) { // group removed - char *szOldName = make_utf8_string(grpchg->pszOldName); - WORD wGroupId = getServListGroupLinkID(szOldName); - - if (wGroupId) { // the group is known, remove from server - servlistPostPacket(nullptr, 0, SSO_BEGIN_OPERATION, 100); // start server modifications here - servlistRemoveGroup(szOldName, wGroupId); - } - SAFE_FREE(&szOldName); - } - else if (grpchg->pszNewName != nullptr && grpchg->pszOldName != nullptr) { // group renamed - char *szNewName = make_utf8_string(grpchg->pszNewName); - char *szOldName = make_utf8_string(grpchg->pszOldName); - WORD wGroupId = getServListGroupLinkID(szOldName); - - if (wGroupId) { // group is known, rename on server - servlistRenameGroup(szOldName, wGroupId, szNewName); - } - SAFE_FREE(&szOldName); - SAFE_FREE(&szNewName); - } - } - else { // change to contact - if (IsICQContact(hContact)) { // our contact, fine move on the server as well - char *szNewName = grpchg->pszNewName ? make_utf8_string(grpchg->pszNewName) : nullptr; - servlistMoveContact(hContact, szNewName); - SAFE_FREE(&szNewName); - } - } - return 0; -} diff --git a/protocols/IcqOscarJ/src/icq_servlist.h b/protocols/IcqOscarJ/src/icq_servlist.h deleted file mode 100644 index 081b509469..0000000000 --- a/protocols/IcqOscarJ/src/icq_servlist.h +++ /dev/null @@ -1,168 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- - -#ifndef __ICQ_SERVLIST_H -#define __ICQ_SERVLIST_H - -// actions: -#define SSA_CHECK_ROSTER 0 // request serv-list -#define SSA_VISIBILITY 1 // update visibility -#define SSA_CONTACT_UPDATE 2 // update contact's details -#define SSA_GROUP_RENAME 5 // rename group -#define SSA_PRIVACY_ADD 0xA // add privacy item -#define SSA_PRIVACY_REMOVE 0xB // remove privacy item -#define SSA_CONTACT_ADD 0x10 // add contact w/o auth -#define SSA_CONTACT_SET_GROUP 0x12 // move to group -#define SSA_CONTACT_REMOVE 0x13 // delete contact -#define SSA_CONTACT_FIX_AUTH 0x40 // reuploading contact for auth re-request -#define SSA_GROUP_ADD 0x15 // create group -#define SSA_GROUP_REMOVE 0x16 // delete group -#define SSA_GROUP_UPDATE 0x17 // update group -#define SSA_SERVLIST_ACK 0x20 // send proto ack only (UploadUI) -#define SSA_SETAVATAR 0x30 -#define SSA_REMOVEAVATAR 0x31 -#define SSA_IMPORT 7 -#define SSA_ACTION_GROUP 0x80 // grouped action - -struct CIcqProto; -// callback prototypes for pending operation mechanism: -typedef int(__cdecl CIcqProto::*PENDING_GROUP_CALLBACK)(const char* pszGroup, WORD wGroupId, LPARAM lParam, int nResult); -typedef int(__cdecl CIcqProto::*PENDING_CONTACT_CALLBACK)(MCONTACT hContact, WORD wContactId, WORD wGroupId, LPARAM lParam, int nResult); - -// cookie struct for SSI actions -struct cookie_servlist_action -{ - MCONTACT hContact; - char *szGroup; - WORD wContactId; - WORD wGroupId; - char *szGroupName; - WORD wNewContactId; - WORD wNewGroupId; - int dwAction; - LPARAM lParam; - int dwGroupCount; - cookie_servlist_action **pGroupItems; -}; - -// server id type groups -#define SSIT_ITEM 0x00000000 -#define SSIT_GROUP 0x00010000 - -// server id flags -#define SSIF_UNHANDLED 0x01000000 - - -// pending operations -#define PENDING_RESULT_SUCCESS 0x00 -#define PENDING_RESULT_INLINE 0x01 -#define PENDING_RESULT_FAILED 0x0F -#define PENDING_RESULT_PURGE 0x10 - -// serv-list update board -#define SSOG_SINGLE 0x00010000 -#define SSOG_DOUBLE 0x00020000 - -#define SSOF_CONTACT 0x00800000 -#define SSOF_BEGIN_OPERATION 0x00100000 -#define SSOF_END_OPERATION 0x00200000 -#define SSOF_IMPORT_OPERATION 0x00400000 - -#define SSOP_ITEM_ACTION 0x01000000 | SSOG_SINGLE -// SSA_PRIVACY_ADD -// SSA_CONTACT_ADD -// SSA_CONTACT_UPDATE -// SSA_VISIBILITY -// SSA_PRIVACY_REMOVE -// SSA_CONTACT_REMOVE -// SSA_SETAVATAR -// SSA_REMOVEAVATAR -#define SSOP_GROUP_ACTION 0x02000000 | SSOG_SINGLE -// SSA_GROUP_ADD -// SSA_GROUP_RENAME -// SSA_GROUP_UPDATE -// SSA_GROUP_REMOVE -#define SSO_CONTACT_SETGROUP 0x04000000 | SSOG_DOUBLE -// SSA_CONTACT_SET_GROUP -#define SSO_CONTACT_FIXAUTH 0x06000000 | SSOG_DOUBLE -// SSA_CONTACT_FIX_AUTH - -#define SSO_BEGIN_OPERATION 0x80000000 -#define SSO_END_OPERATION 0x40000000 - -#define SSOF_SEND_DIRECTLY 0x10000000 - -#define SSOF_ACTIONMASK 0x0000FFFF -#define SSOF_GROUPINGMASK 0x0F0FFFFF - - -#define MAX_SERVLIST_PACKET_ITEMS 200 - -// server-list request handler item -struct servlistgroupitem -{ // generic parent - DWORD dwOperation; - cookie_servlist_action* cookie; - icq_packet packet; - // perhaps add some dummy bytes -}; - -struct servlistgroupitemdouble : public servlistgroupitem -{ - icq_packet packet2; - WORD wAction2; -}; - -struct ssiqueueditems -{ - time_t tAdded; - int dwTimeout; - int nItems; - servlistgroupitem* pItems[MAX_SERVLIST_PACKET_ITEMS]; -}; - - -// cookie structs for pending records -struct servlistpendingoperation -{ - DWORD flags; - PENDING_GROUP_CALLBACK callback; - LPARAM param; -}; - -struct servlistpendingitem -{ - int nType; - MCONTACT hContact; - char* szGroup; - WORD wContactID; - WORD wGroupID; - - servlistpendingoperation* operations; - int operationsCount; -}; - - -#endif /* __ICQ_SERVLIST_H */ diff --git a/protocols/IcqOscarJ/src/icq_uploadui.cpp b/protocols/IcqOscarJ/src/icq_uploadui.cpp deleted file mode 100644 index 8b35afbed6..0000000000 --- a/protocols/IcqOscarJ/src/icq_uploadui.cpp +++ /dev/null @@ -1,873 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2008 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// Implements Manage Server List dialog -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -static int bListInit = 0; -static HANDLE hItemAll; -static int dwUploadDelay = 1000; // initial setting, it is too low for icq server but good for short updates - -static HWND hwndUploadContacts = nullptr; -static const UINT settingsControls[] = { IDOK }; - -static WORD *pwGroupIds = nullptr; -static int cbGroupIds = 0; - -// Init default clist options -static void ResetCListOptions(HWND hwndList) -{ - SetWindowLongPtr(hwndList, GWL_STYLE, GetWindowLongPtr(hwndList, GWL_STYLE) | CLS_SHOWHIDDEN); - SendMessage(hwndList, CLM_SETHIDEEMPTYGROUPS, (WPARAM)TRUE, 0); -} - -// Selects the "All contacts" checkbox if all other list entries -// are selected, deselects it if not. -static void UpdateAllContactsCheckmark(HWND hwndList, CIcqProto* ppro, HANDLE phItemAll) -{ - int check = 1; - - for (auto &hContact : ppro->AccContacts()) { - HANDLE hItem = (HANDLE)SendMessage(hwndList, CLM_FINDCONTACT, hContact, 0); - if (hItem) { - if (!SendMessage(hwndList, CLM_GETCHECKMARK, (WPARAM)hItem, 0)) { // if any of our contacts is unchecked, uncheck all contacts as well - check = 0; - break; - } - } - } - - SendMessage(hwndList, CLM_SETCHECKMARK, (WPARAM)phItemAll, check); -} - -// Loop over all contacts and update the checkmark -// that indicates wether or not they are already uploaded -static int UpdateCheckmarks(HWND hwndList, CIcqProto* ppro, HANDLE phItemAll) -{ - int bAll = 1; - bListInit = 1; // lock CLC events - - for (auto &hContact : ppro->AccContacts()) { - HANDLE hItem = (HANDLE)SendMessage(hwndList, CLM_FINDCONTACT, hContact, 0); - if (hItem) { - if (ppro->getWord(hContact, DBSETTING_SERVLIST_ID, 0)) - SendMessage(hwndList, CLM_SETCHECKMARK, (WPARAM)hItem, 1); - else - bAll = 0; - } - } - - // Update the "All contacts" checkmark - if (phItemAll) - SendMessage(hwndList, CLM_SETCHECKMARK, (WPARAM)phItemAll, bAll); - - bListInit = 0; - - return bAll; -} - -static void DeleteOtherContactsFromControl(HWND hCtrl, CIcqProto* ppro) -{ - for (auto &hContact : Contacts()) { - HANDLE hItem = (HANDLE)SendMessage(hCtrl, CLM_FINDCONTACT, hContact, 0); - if (hItem) - if (!ppro->IsICQContact(hContact)) - SendMessage(hCtrl, CLM_DELETEITEM, (WPARAM)hItem, 0); - } -} - -static void AppendToUploadLog(HWND hwndDlg, const char *fmt, ...) -{ - va_list va; - char szText[1024]; - int iItem; - - va_start(va, fmt); - mir_vsnprintf(szText, sizeof(szText), fmt, va); - va_end(va); - - iItem = ListBoxAddStringUtf(GetDlgItem(hwndDlg, IDC_LOG), szText); - SendDlgItemMessage(hwndDlg, IDC_LOG, LB_SETTOPINDEX, iItem, 0); -} - -static void DeleteLastUploadLogLine(HWND hwndDlg) -{ - SendDlgItemMessage(hwndDlg, IDC_LOG, LB_DELETESTRING, SendDlgItemMessage(hwndDlg, IDC_LOG, LB_GETCOUNT, 0, 0) - 1, 0); -} - -static void GetLastUploadLogLine(HWND hwndDlg, char *szBuf, size_t cbBuf) -{ - WCHAR str[MAX_PATH]; - SendDlgItemMessageW(hwndDlg, IDC_LOG, LB_GETTEXT, SendDlgItemMessage(hwndDlg, IDC_LOG, LB_GETCOUNT, 0, 0) - 1, (LPARAM)str); - make_utf8_string_static(str, szBuf, cbBuf); -} - -static int GroupEnumIdsEnumProc(const char *szSetting, void *lParam) -{ - // it is probably server group - if (szSetting && mir_strlen(szSetting) < 5) { - char val[MAX_PATH + 2]; // dummy - if (db_get_static(NULL, (char*)lParam, szSetting, val, MAX_PATH)) - return 0; // this converts all string types to DBVT_ASCIIZ - - pwGroupIds = (WORD*)SAFE_REALLOC(pwGroupIds, (cbGroupIds + 1) * sizeof(WORD)); - pwGroupIds[cbGroupIds] = (WORD)strtoul(szSetting, nullptr, 0x10); - cbGroupIds++; - } - return 0; -} - -static void enumServerGroups(CIcqProto* ppro) -{ - char szModule[MAX_PATH + 9]; - mir_snprintf(szModule, "%s%s", ppro->m_szModuleName, "SrvGroups"); - db_enum_settings(NULL, &GroupEnumIdsEnumProc, szModule, szModule); -} - -static DWORD sendUploadGroup(CIcqProto* ppro, WORD wAction, WORD wGroupId, char* szItemName) -{ - DWORD dwCookie; - cookie_servlist_action* ack; - - if (ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action))) { // we have cookie good, go on - ack->wGroupId = wGroupId; - ack->dwAction = SSA_SERVLIST_ACK; - dwCookie = ppro->AllocateCookie(CKT_SERVERLIST, wAction, 0, ack); - ack->lParam = dwCookie; - - ppro->icq_sendServerGroup(dwCookie, wAction, ack->wGroupId, szItemName, nullptr, 0, 0); - return dwCookie; - } - return 0; -} - -static DWORD sendUploadBuddy(CIcqProto* ppro, MCONTACT hContact, WORD wAction, DWORD dwUin, char *szUID, WORD wContactId, WORD wGroupId, WORD wItemType) -{ - cookie_servlist_action *ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action)); - if (ack == nullptr) - return 0; - - // we have cookie good, go on - ack->hContact = hContact; - ack->wContactId = wContactId; - ack->wGroupId = wGroupId; - ack->dwAction = SSA_SERVLIST_ACK; - DWORD dwCookie = ppro->AllocateCookie(CKT_SERVERLIST, wAction, hContact, ack); - ack->lParam = dwCookie; - - if (wItemType == SSI_ITEM_BUDDY) - ppro->icq_sendServerContact(hContact, dwCookie, wAction, ack->wGroupId, ack->wContactId, SSOP_ITEM_ACTION | SSOF_CONTACT, 500, nullptr); - else - ppro->icq_sendSimpleItem(dwCookie, wAction, dwUin, szUID, ack->wGroupId, ack->wContactId, wItemType, SSOP_ITEM_ACTION, 500); - - return dwCookie; -} - -static char* getServerResultDesc(int wCode) -{ - switch (wCode) { - case 0: return LPGEN("OK"); - case 2: return LPGEN("NOT FOUND"); - case 3: return LPGEN("ALREADY EXISTS"); - case 0xA: return LPGEN("INVALID DATA"); - case 0xC: return LPGEN("LIST FULL"); - default: return LPGEN("FAILED"); - } -} - -#define ACTION_NONE 0 -#define ACTION_ADDBUDDY 1 -#define ACTION_ADDBUDDYAUTH 2 -#define ACTION_REMOVEBUDDY 3 -#define ACTION_ADDGROUP 4 -#define ACTION_REMOVEGROUP 5 -#define ACTION_UPDATESTATE 6 -#define ACTION_MOVECONTACT 7 -#define ACTION_ADDVISIBLE 8 -#define ACTION_REMOVEVISIBLE 9 -#define ACTION_ADDINVISIBLE 10 -#define ACTION_REMOVEINVISIBLE 11 - -#define STATE_READY 1 -#define STATE_REGROUP 2 -#define STATE_ITEMS 3 -#define STATE_VISIBILITY 5 -#define STATE_CONSOLIDATE 4 - -#define M_PROTOACK (WM_USER+100) -#define M_UPLOADMORE (WM_USER+101) -#define M_INITCLIST (WM_USER+102) - -static INT_PTR CALLBACK DlgProcUploadList(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - CIcqProto* ppro = (CIcqProto*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - - static int working; - static HANDLE hProtoAckHook; - static int currentSequence; - static int currentAction; - static int currentState; - static MCONTACT hCurrentContact; - static int lastAckResult = 0; - static WORD wNewContactId; - static WORD wNewGroupId; - static char *szNewGroupName; - static WORD wNewVisibilityId; - - switch (message) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam); - { - char str[MAX_PATH]; - - working = 0; - hProtoAckHook = nullptr; - currentState = STATE_READY; - - ResetCListOptions(GetDlgItem(hwndDlg, IDC_CLIST)); - - AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("Select contacts you want to store on server."), str, MAX_PATH)); - AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("Ready..."), str, MAX_PATH)); - } - return TRUE; - - // The M_PROTOACK message is received when the - // server has responded to our last update packet - case M_PROTOACK: - { - int bMulti = 0; - ACKDATA *ack = (ACKDATA*)lParam; - char szLastLogLine[MAX_PATH]; - char str[MAX_PATH]; - - // Is this an ack we are waiting for? - if (mir_strcmp(ack->szModule, ppro->m_szModuleName)) - break; - - if (ack->type == ICQACKTYPE_RATEWARNING) { // we are sending tooo fast, slow down the process - if (ack->hProcess != (HANDLE)1) break; // check class - if (ack->lParam == 2 || ack->lParam == 3) { // check status - GetLastUploadLogLine(hwndDlg, szLastLogLine, MAX_PATH); - DeleteLastUploadLogLine(hwndDlg); - AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("Server rate warning -> slowing down the process."), str, MAX_PATH)); - AppendToUploadLog(hwndDlg, szLastLogLine); - - dwUploadDelay *= 2; - - break; - } - if (ack->lParam == 4) dwUploadDelay /= 2; // the rate is ok, turn up - } - - if (ack->type != ICQACKTYPE_SERVERCLIST) - break; - - if ((INT_PTR)ack->hProcess != currentSequence) - break; - - lastAckResult = ack->result == ACKRESULT_SUCCESS ? 0 : 1; - - switch (currentAction) { - case ACTION_ADDBUDDY: - if (ack->result == ACKRESULT_SUCCESS) { - ppro->setByte(hCurrentContact, "Auth", 0); - ppro->setWord(hCurrentContact, DBSETTING_SERVLIST_ID, wNewContactId); - ppro->setWord(hCurrentContact, DBSETTING_SERVLIST_GROUP, wNewGroupId); - break; - } - else { // If the server refused to add the contact without authorization, - // we try again _with_ authorization TLV - ppro->setByte(hCurrentContact, "Auth", 1); - - DWORD dwUIN; - uid_str szUID; - if (!ppro->getContactUid(hCurrentContact, &dwUIN, &szUID)) { - currentAction = ACTION_ADDBUDDYAUTH; - currentSequence = sendUploadBuddy(ppro, hCurrentContact, ICQ_LISTS_ADDTOLIST, dwUIN, szUID, wNewContactId, wNewGroupId, SSI_ITEM_BUDDY); - } - - return FALSE; - } - - case ACTION_ADDBUDDYAUTH: - if (ack->result == ACKRESULT_SUCCESS) { - ppro->setWord(hCurrentContact, DBSETTING_SERVLIST_ID, wNewContactId); - ppro->setWord(hCurrentContact, DBSETTING_SERVLIST_GROUP, wNewGroupId); - } - else { - db_unset(hCurrentContact, ppro->m_szModuleName, "Auth"); - ppro->FreeServerID(wNewContactId, SSIT_ITEM); - } - break; - - case ACTION_REMOVEBUDDY: - if (ack->result == ACKRESULT_SUCCESS) { // clear obsolete settings - ppro->FreeServerID(wNewContactId, SSIT_ITEM); - db_unset(hCurrentContact, ppro->m_szModuleName, DBSETTING_SERVLIST_ID); - db_unset(hCurrentContact, ppro->m_szModuleName, DBSETTING_SERVLIST_GROUP); - db_unset(hCurrentContact, ppro->m_szModuleName, "Auth"); - } - break; - - case ACTION_ADDGROUP: - if (ack->result == ACKRESULT_SUCCESS) { - ppro->setServListGroupName(wNewGroupId, szNewGroupName); // add group to list - ppro->setServListGroupLinkID(szNewGroupName, wNewGroupId); // grouppath is known - - int groupSize; - void *groupData = ppro->collectGroups(&groupSize); - groupData = SAFE_REALLOC(groupData, groupSize + 2); - *(((WORD*)groupData) + (groupSize >> 1)) = wNewGroupId; // add this new group id - groupSize += 2; - - cookie_servlist_action *action = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action)); - if (action) { - DWORD dwCookie; // we do not use this - - action->dwAction = SSA_SERVLIST_ACK; - dwCookie = ppro->AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_UPDATEGROUP, 0, action); - - ppro->icq_sendServerGroup(dwCookie, ICQ_LISTS_UPDATEGROUP, 0, action->szGroupName, groupData, groupSize, 0); - } - SAFE_FREE((void**)&groupData); - } - else ppro->FreeServerID(wNewGroupId, SSIT_GROUP); - - SAFE_FREE((void**)&szNewGroupName); - break; - - case ACTION_REMOVEGROUP: - if (ack->result == ACKRESULT_SUCCESS) { - ppro->FreeServerID(wNewGroupId, SSIT_GROUP); - ppro->setServListGroupName(wNewGroupId, nullptr); // remove group from list - ppro->removeGroupPathLinks(wNewGroupId); // grouppath is known - - int groupSize; - void *groupData = ppro->collectGroups(&groupSize); - - cookie_servlist_action *action = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action)); - if (action) { - DWORD dwCookie; // we do not use this - - action->dwAction = SSA_SERVLIST_ACK; - dwCookie = ppro->AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_UPDATEGROUP, 0, action); - - ppro->icq_sendServerGroup(dwCookie, ICQ_LISTS_UPDATEGROUP, 0, action->szGroupName, groupData, groupSize, 0); - } - SAFE_FREE((void**)&groupData); - } - break; - - case ACTION_UPDATESTATE: - // do nothing - break; - - case ACTION_MOVECONTACT: - if (ack->result == ACKRESULT_SUCCESS) { - ppro->FreeServerID(ppro->getWord(hCurrentContact, DBSETTING_SERVLIST_ID, 0), SSIT_ITEM); - ppro->setWord(hCurrentContact, DBSETTING_SERVLIST_ID, wNewContactId); - ppro->setWord(hCurrentContact, DBSETTING_SERVLIST_GROUP, wNewGroupId); - dwUploadDelay *= 2; // we double the delay here (2 packets) - } - break; - - case ACTION_ADDVISIBLE: - if (ack->result == ACKRESULT_SUCCESS) - ppro->setWord(hCurrentContact, DBSETTING_SERVLIST_PERMIT, wNewContactId); - else - ppro->FreeServerID(wNewContactId, SSIT_ITEM); - break; - - case ACTION_ADDINVISIBLE: - if (ack->result == ACKRESULT_SUCCESS) - ppro->setWord(hCurrentContact, DBSETTING_SERVLIST_DENY, wNewContactId); - else - ppro->FreeServerID(wNewContactId, SSIT_ITEM); - break; - - case ACTION_REMOVEVISIBLE: - if (ack->result == ACKRESULT_SUCCESS) { - ppro->FreeServerID(wNewContactId, SSIT_ITEM); - ppro->setWord(hCurrentContact, DBSETTING_SERVLIST_PERMIT, 0); - } - break; - - case ACTION_REMOVEINVISIBLE: - if (ack->result == ACKRESULT_SUCCESS) { - ppro->FreeServerID(wNewContactId, SSIT_ITEM); - ppro->setWord(hCurrentContact, DBSETTING_SERVLIST_DENY, 0); - } - break; - } - - // Update the log window - GetLastUploadLogLine(hwndDlg, szLastLogLine, MAX_PATH); - DeleteLastUploadLogLine(hwndDlg); - AppendToUploadLog(hwndDlg, "%s%s", szLastLogLine, - ICQTranslateUtfStatic(getServerResultDesc(ack->lParam), str, MAX_PATH)); - - if (!bMulti) - SetTimer(hwndDlg, M_UPLOADMORE, dwUploadDelay, nullptr); // delay - } - break; - - case WM_TIMER: - switch (wParam) { - case M_UPLOADMORE: - KillTimer(hwndDlg, M_UPLOADMORE); - if (currentAction == ACTION_MOVECONTACT) - dwUploadDelay /= 2; // turn it back - - PostMessage(hwndDlg, M_UPLOADMORE, 0, 0); - return 0; - } - - // The M_UPLOADMORE window message is received when the user presses 'Update' - // and every time an ack from the server has been taken care of. - case M_UPLOADMORE: - { - char str[MAX_PATH]; - - switch (currentState) { - case STATE_REGROUP: - // TODO: iterate over all checked groups and create if needed - // if creation requires reallocation of groups do it here - currentState = STATE_ITEMS; - hCurrentContact = NULL; - PostMessage(hwndDlg, M_UPLOADMORE, 0, 0); - break; - - case STATE_ITEMS: - // Iterate over all contacts until one is found that - // needs to be updated on the server - MCONTACT hContact; - if (hCurrentContact == NULL) - hContact = db_find_first(ppro->m_szModuleName); - else { // we do not want to go thru all contacts over and over again - hContact = hCurrentContact; - if (lastAckResult) // if the last operation on this contact fail, do not do it again, go to next - hContact = db_find_next(hContact, ppro->m_szModuleName); - } - - while (hContact) { - hCurrentContact = hContact; - - HWND hwndList = GetDlgItem(hwndDlg, IDC_CLIST); - HANDLE hItem = (HANDLE)SendMessage(hwndList, CLM_FINDCONTACT, hContact, 0); - if (hItem) { - int isChecked = SendMessage(hwndList, CLM_GETCHECKMARK, (WPARAM)hItem, 0) != 0; - int isOnServer = ppro->getWord(hContact, DBSETTING_SERVLIST_ID, 0) != 0; - - DWORD dwUin; - uid_str szUid; - BOOL bUidOk = !ppro->getContactUid(hContact, &dwUin, &szUid); - - // Is this one out of sync? - if (bUidOk && (isChecked != isOnServer)) { - // Only upload custom nicks - char *pszNick = ppro->getSettingStringUtf(hContact, "CList", "MyHandle", nullptr); - - if (isChecked) { // Queue for uploading - char *pszGroup = ppro->getContactCListGroup(hContact); - if (!mir_strlen(pszGroup)) - pszGroup = null_strdup(DEFAULT_SS_GROUP); - - // Get group ID from cache, if not ready use parent group, if still not ready create one - wNewGroupId = ppro->getServListGroupLinkID(pszGroup); - if (!wNewGroupId && strstrnull(pszGroup, "\\") != nullptr) { // if it is sub-group, take master parent - strstrnull(pszGroup, "\\")[0] = '\0'; - wNewGroupId = ppro->getServListGroupLinkID(pszGroup); - } - if (!wNewGroupId && currentAction != ACTION_ADDGROUP) { // if the group still does not exist and there was no try before, try to add group - AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("Adding group \"%s\"..."), str, MAX_PATH), pszGroup); - - wNewGroupId = ppro->GenerateServerID(SSIT_GROUP, 0); // ??? - szNewGroupName = pszGroup; - currentAction = ACTION_ADDGROUP; - currentSequence = sendUploadGroup(ppro, ICQ_LISTS_ADDTOLIST, wNewGroupId, pszGroup); - SAFE_FREE(&pszNick); - return FALSE; - } - - SAFE_FREE(&pszGroup); - - AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("Uploading %s..."), str, MAX_PATH), pszNick ? pszNick : strUID(dwUin, szUid)); - - currentAction = ACTION_ADDBUDDY; - - if (wNewGroupId) { - wNewContactId = ppro->GenerateServerID(SSIT_ITEM, 0); - - currentSequence = sendUploadBuddy(ppro, hCurrentContact, ICQ_LISTS_ADDTOLIST, dwUin, szUid, - wNewContactId, wNewGroupId, SSI_ITEM_BUDDY); - SAFE_FREE(&pszNick); - return FALSE; - } - - char szLastLogLine[MAX_PATH]; - // Update the log window with the failure and continue with next contact - GetLastUploadLogLine(hwndDlg, szLastLogLine, MAX_PATH); - DeleteLastUploadLogLine(hwndDlg); - AppendToUploadLog(hwndDlg, "%s%s", szLastLogLine, ICQTranslateUtfStatic(LPGEN("FAILED"), str, MAX_PATH)); - AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("No upload group available"), str, MAX_PATH)); - ppro->debugLogA("Upload failed, no group"); - currentState = STATE_READY; - } - else { // Queue for deletion - if (pszNick) - AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("Deleting %s..."), str, MAX_PATH), pszNick); - else - AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("Deleting %s..."), str, MAX_PATH), strUID(dwUin, szUid)); - - wNewGroupId = ppro->getWord(hContact, DBSETTING_SERVLIST_GROUP, 0); - wNewContactId = ppro->getWord(hContact, DBSETTING_SERVLIST_ID, 0); - currentAction = ACTION_REMOVEBUDDY; - currentSequence = sendUploadBuddy(ppro, hContact, ICQ_LISTS_REMOVEFROMLIST, dwUin, szUid, - wNewContactId, wNewGroupId, SSI_ITEM_BUDDY); - } - SAFE_FREE((void**)&pszNick); - break; - } - - // the contact is and should be on server, check if it is in correct group, move otherwise - if (bUidOk && isChecked) { - WORD wCurrentGroupId = ppro->getWord(hContact, DBSETTING_SERVLIST_GROUP, 0); - - char *pszGroup = ppro->getContactCListGroup(hContact); - if (!mir_strlen(pszGroup)) - pszGroup = null_strdup(DEFAULT_SS_GROUP); - - wNewGroupId = ppro->getServListGroupLinkID(pszGroup); - if (!wNewGroupId && strstrnull(pszGroup, "\\") != nullptr) { // if it is sub-group, take master parent - strstrnull(pszGroup, "\\")[0] = '\0'; - wNewGroupId = ppro->getServListGroupLinkID(pszGroup); - } - - // if the group still does not exist and there was no try before, try to add group - if (!wNewGroupId && currentAction != ACTION_ADDGROUP) { - AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("Adding group \"%s\"..."), str, MAX_PATH), pszGroup); - - wNewGroupId = ppro->GenerateServerID(SSIT_GROUP, 0); - szNewGroupName = pszGroup; - currentAction = ACTION_ADDGROUP; - currentSequence = sendUploadGroup(ppro, ICQ_LISTS_ADDTOLIST, wNewGroupId, pszGroup); - return FALSE; - } - - // we have a group the contact should be in, move it - if (wNewGroupId && (wNewGroupId != wCurrentGroupId)) { - WORD wCurrentContactId = ppro->getWord(hContact, DBSETTING_SERVLIST_ID, 0); - - char *pszNick = ppro->getSettingStringUtf(hContact, "CList", "MyHandle", nullptr); - if (pszNick) - AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("Moving %s to group \"%s\"..."), str, MAX_PATH), pszNick, pszGroup); - else - AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("Moving %s to group \"%s\"..."), str, MAX_PATH), strUID(dwUin, szUid), pszGroup); - - currentAction = ACTION_MOVECONTACT; - wNewContactId = ppro->GenerateServerID(SSIT_ITEM, 0); - sendUploadBuddy(ppro, hContact, ICQ_LISTS_REMOVEFROMLIST, dwUin, szUid, wCurrentContactId, wCurrentGroupId, SSI_ITEM_BUDDY); - currentSequence = sendUploadBuddy(ppro, hContact, ICQ_LISTS_ADDTOLIST, dwUin, szUid, wNewContactId, wNewGroupId, SSI_ITEM_BUDDY); - SAFE_FREE((void**)&pszNick); - SAFE_FREE((void**)&pszGroup); - - break; - } - SAFE_FREE((void**)&pszGroup); - } - } - hContact = db_find_next(hContact); - } - if (!hContact) { - currentState = STATE_VISIBILITY; - hCurrentContact = NULL; - PostMessage(hwndDlg, M_UPLOADMORE, 0, 0); - } - break; - - case STATE_VISIBILITY: - // Iterate over all contacts until one is found that - // needs to be updated on the server - if (hCurrentContact == NULL) - hContact = db_find_first(ppro->m_szModuleName); - else { // we do not want to go thru all contacts over and over again - hContact = hCurrentContact; - if (lastAckResult) // if the last operation on this contact fail, do not do it again, go to next - hContact = db_find_next(hContact, ppro->m_szModuleName); - } - - while (hContact) { - WORD wApparentMode = ppro->getWord(hContact, "ApparentMode", 0); - WORD wDenyId = ppro->getWord(hContact, DBSETTING_SERVLIST_DENY, 0); - WORD wPermitId = ppro->getWord(hContact, DBSETTING_SERVLIST_PERMIT, 0); - WORD wIgnoreId = ppro->getWord(hContact, DBSETTING_SERVLIST_IGNORE, 0); - - hCurrentContact = hContact; - - DWORD dwUin; - uid_str szUid; - ppro->getContactUid(hContact, &dwUin, &szUid); - - if (wApparentMode == ID_STATUS_ONLINE) { // contact is on the visible list - if (wPermitId == 0) { - currentAction = ACTION_ADDVISIBLE; - wNewContactId = ppro->GenerateServerID(SSIT_ITEM, 0); - AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("Adding %s to visible list..."), str, MAX_PATH), strUID(dwUin, szUid)); - currentSequence = sendUploadBuddy(ppro, hContact, ICQ_LISTS_ADDTOLIST, dwUin, szUid, wNewContactId, 0, SSI_ITEM_PERMIT); - break; - } - } - if (wApparentMode == ID_STATUS_OFFLINE) { // contact is on the invisible list - if (wDenyId == 0 && wIgnoreId == 0) { - currentAction = ACTION_ADDINVISIBLE; - wNewContactId = ppro->GenerateServerID(SSIT_ITEM, 0); - AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("Adding %s to invisible list..."), str, MAX_PATH), strUID(dwUin, szUid)); - currentSequence = sendUploadBuddy(ppro, hContact, ICQ_LISTS_ADDTOLIST, dwUin, szUid, wNewContactId, 0, SSI_ITEM_DENY); - break; - } - } - if (wApparentMode != ID_STATUS_ONLINE) { // contact is not on visible list - if (wPermitId != 0) { - currentAction = ACTION_REMOVEVISIBLE; - wNewContactId = wPermitId; - AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("Deleting %s from visible list..."), str, MAX_PATH), strUID(dwUin, szUid)); - currentSequence = sendUploadBuddy(ppro, hContact, ICQ_LISTS_REMOVEFROMLIST, dwUin, szUid, wNewContactId, 0, SSI_ITEM_PERMIT); - break; - } - } - if (wApparentMode != ID_STATUS_OFFLINE) { // contact is not on invisible list - if (wDenyId != 0) { - currentAction = ACTION_REMOVEINVISIBLE; - wNewContactId = wDenyId; - AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("Deleting %s from invisible list..."), str, MAX_PATH), strUID(dwUin, szUid)); - currentSequence = sendUploadBuddy(ppro, hContact, ICQ_LISTS_REMOVEFROMLIST, dwUin, szUid, wNewContactId, 0, SSI_ITEM_DENY); - break; - } - } - hContact = db_find_next(hContact); - } - if (!hContact) { - currentState = STATE_CONSOLIDATE; - AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("Cleaning groups"), str, MAX_PATH)); - EnableDlgItem(hwndDlg, IDCANCEL, FALSE); - enumServerGroups(ppro); - PostMessage(hwndDlg, M_UPLOADMORE, 0, 0); - } - break; - - case STATE_CONSOLIDATE: // updage group data, remove redundant groups - if (currentAction == ACTION_UPDATESTATE) - DeleteLastUploadLogLine(hwndDlg); - - if (cbGroupIds) { // some groups in the list - void* groupData; - int groupSize; - - cbGroupIds--; - wNewGroupId = pwGroupIds[cbGroupIds]; - - if (groupData = ppro->collectBuddyGroup(wNewGroupId, &groupSize)) { // the group is still not empty, just update it - char *pszGroup = ppro->getServListGroupName(wNewGroupId); - cookie_servlist_action* ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action)); - - ack->dwAction = SSA_SERVLIST_ACK; - ack->wGroupId = wNewGroupId; - currentSequence = ppro->AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_UPDATEGROUP, 0, ack); - ack->lParam = currentSequence; - currentAction = ACTION_UPDATESTATE; - AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("Updating group \"%s\"..."), str, MAX_PATH), pszGroup); - - ppro->icq_sendServerGroup(currentSequence, ICQ_LISTS_UPDATEGROUP, wNewGroupId, pszGroup, groupData, groupSize, 0); - - SAFE_FREE((void**)&pszGroup); - } - else { // the group is empty, delete it if it does not have sub-groups - if (!ppro->CheckServerID((WORD)(wNewGroupId + 1), 0) || ppro->getServListGroupLevel((WORD)(wNewGroupId + 1)) == 0) { // is next id an sub-group, if yes, we cannot delete this group - char *pszGroup = ppro->getServListGroupName(wNewGroupId); - currentAction = ACTION_REMOVEGROUP; - AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("Deleting group \"%s\"..."), str, MAX_PATH), pszGroup); - currentSequence = sendUploadGroup(ppro, ICQ_LISTS_REMOVEFROMLIST, wNewGroupId, pszGroup); - SAFE_FREE((void**)&pszGroup); - } - else { // update empty group - char *pszGroup = ppro->getServListGroupName(wNewGroupId); - cookie_servlist_action *ack = (cookie_servlist_action*)SAFE_MALLOC(sizeof(cookie_servlist_action)); - - ack->dwAction = SSA_SERVLIST_ACK; - ack->wGroupId = wNewGroupId; - currentSequence = ppro->AllocateCookie(CKT_SERVERLIST, ICQ_LISTS_UPDATEGROUP, 0, ack); - ack->lParam = currentSequence; - currentAction = ACTION_UPDATESTATE; - AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("Updating group \"%s\"..."), str, MAX_PATH), pszGroup); - - ppro->icq_sendServerGroup(currentSequence, ICQ_LISTS_UPDATEGROUP, wNewGroupId, pszGroup, nullptr, 0, 0); - - SAFE_FREE((void**)&pszGroup); - } - } - SAFE_FREE((void**)&groupData); // free the memory - } - else { // all groups processed - SAFE_FREE((void**)&pwGroupIds); - currentState = STATE_READY; - } - break; - } - - if (currentState == STATE_READY) { - // All contacts are in sync - AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("All operations complete"), str, MAX_PATH)); - EnableDlgItem(hwndDlg, IDCANCEL, TRUE); - SetDlgItemText(hwndDlg, IDCANCEL, TranslateT("Close")); - - // end server modifications here - ppro->servlistPostPacket(nullptr, 0, SSO_END_OPERATION, 100); - working = 0; - UpdateCheckmarks(GetDlgItem(hwndDlg, IDC_CLIST), ppro, hItemAll); - if (hProtoAckHook) - UnhookEvent(hProtoAckHook); - } - } - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDOK: - SendDlgItemMessage(hwndDlg, IDC_LOG, LB_RESETCONTENT, 0, 0); - if (!ppro->icqOnline()) { - char str[MAX_PATH]; - AppendToUploadLog(hwndDlg, ICQTranslateUtfStatic(LPGEN("You have to be online to synchronize the server-list!"), str, MAX_PATH)); - break; - } - working = 1; - hCurrentContact = NULL; - currentState = STATE_REGROUP; - currentAction = ACTION_NONE; - icq_ShowMultipleControls(hwndDlg, settingsControls, _countof(settingsControls), SW_HIDE); - EnableDlgItem(hwndDlg, IDC_CLIST, FALSE); - hProtoAckHook = HookEventMessage(ME_PROTO_ACK, hwndDlg, M_PROTOACK); - - // start server modifications here - ppro->servlistPostPacket(nullptr, 0, SSO_BEGIN_OPERATION | SSOF_IMPORT_OPERATION, 100); - PostMessage(hwndDlg, M_UPLOADMORE, 0, 0); - break; - - case IDCANCEL: // TODO: this must be clean - DestroyWindow(hwndDlg); - break; - } - break; - - case WM_NOTIFY: - if (((NMHDR*)lParam)->idFrom == IDC_CLIST) { - HWND hClist = GetDlgItem(hwndDlg, IDC_CLIST); - - switch (((NMHDR*)lParam)->code) { - case CLN_OPTIONSCHANGED: - ResetCListOptions(hClist); - break; - - case CLN_NEWCONTACT: - case CLN_CONTACTMOVED: - // Delete non-icq contacts - DeleteOtherContactsFromControl(hClist, ppro); - if (hItemAll) - UpdateAllContactsCheckmark(hClist, ppro, hItemAll); - break; - - case CLN_LISTREBUILT: - { - int bCheck = false; - - // Delete non-icq contacts - if (ppro) { - DeleteOtherContactsFromControl(hClist, ppro); - if (!bListInit) // do not enter twice - bCheck = UpdateCheckmarks(hClist, ppro, nullptr); - } - - if (!hItemAll) { // Add the "All contacts" item - CLCINFOITEM cii = { 0 }; - cii.cbSize = sizeof(cii); - cii.flags = CLCIIF_GROUPFONT | CLCIIF_CHECKBOX; - cii.pszText = TranslateT("** All contacts **"); - hItemAll = (HANDLE)SendMessage(hClist, CLM_ADDINFOITEM, 0, (LPARAM)&cii); - } - - SendMessage(hClist, CLM_SETCHECKMARK, (WPARAM)hItemAll, bCheck); - } - break; - - case CLN_CHECKCHANGED: - if (!bListInit) { - NMCLISTCONTROL *nm = (NMCLISTCONTROL*)lParam; - if (nm->flags&CLNF_ISINFO) { - int check = SendMessage(hClist, CLM_GETCHECKMARK, (WPARAM)hItemAll, 0); - - for (auto &hContact : ppro->AccContacts()) { - HANDLE hItem = (HANDLE)SendMessage(hClist, CLM_FINDCONTACT, hContact, 0); - if (hItem) - SendMessage(hClist, CLM_SETCHECKMARK, (WPARAM)hItem, check); - } - } - else UpdateAllContactsCheckmark(hClist, ppro, hItemAll); - } - break; - } - } - break; - - case WM_CLOSE: - DestroyWindow(hwndDlg); - break; - - case WM_DESTROY: - if (hProtoAckHook) - UnhookEvent(hProtoAckHook); - if (working) // end server modifications here - ppro->servlistPostPacket(nullptr, 0, SSO_END_OPERATION, 100); - - hwndUploadContacts = nullptr; - working = 0; - break; - } - - return FALSE; -} - -void CIcqProto::ShowUploadContactsDialog(void) -{ - if (hwndUploadContacts == nullptr) { - hItemAll = nullptr; - hwndUploadContacts = CreateDialogParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_ICQUPLOADLIST), nullptr, DlgProcUploadList, LPARAM(this)); - } - - SetForegroundWindow(hwndUploadContacts); -} diff --git a/protocols/IcqOscarJ/src/icq_xstatus.cpp b/protocols/IcqOscarJ/src/icq_xstatus.cpp deleted file mode 100644 index 365d39b586..0000000000 --- a/protocols/IcqOscarJ/src/icq_xstatus.cpp +++ /dev/null @@ -1,1133 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Angeli-Ka, Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// Support for Custom Statuses -// ----------------------------------------------------------------------------- - -#include "stdafx.h" -#include "m_extraicons.h" -#include "../icq_xstatus/src/resource.h" - -static HANDLE hXStatusIcons[XSTATUS_COUNT]; -static int hXStatusCListIcons[XSTATUS_COUNT]; -static BOOL bXStatusCListIconsValid[XSTATUS_COUNT]; - -int OnReloadIcons(WPARAM, LPARAM) -{ - memset(bXStatusCListIconsValid, 0, sizeof(bXStatusCListIconsValid)); - return 0; -} - -BYTE CIcqProto::getContactXStatus(MCONTACT hContact) -{ - if (!m_bXStatusEnabled && !m_bMoodsEnabled) - return 0; - - BYTE bXStatus = getByte(hContact, DBSETTING_XSTATUS_ID, 0); - return (bXStatus < 1 || bXStatus > XSTATUS_COUNT) ? 0 : bXStatus; -} - -DWORD CIcqProto::sendXStatusDetailsRequest(MCONTACT hContact, int bForced) -{ - DWORD dwCookie = 0; - - // only request custom status detail when the contact has one - if (m_bXStatusEnabled && getContactXStatus(hContact) != 0) { - int nNotifyLen = 94 + UINMAXLEN; - char *szNotify = (char*)_alloca(nNotifyLen); - - mir_snprintf(szNotify, nNotifyLen, "cAwaySrvAwayStat1%d", m_dwLocalUIN); - - dwCookie = SendXtrazNotifyRequest(hContact, "srvMng", szNotify, bForced); - } - return dwCookie; -} - -DWORD CIcqProto::requestXStatusDetails(MCONTACT hContact, BOOL bAllowDelay) -{ - if (!validateStatusMessageRequest(hContact, MTYPE_SCRIPT_NOTIFY)) - return 0; // apply privacy rules - - if (!CheckContactCapabilities(hContact, CAPF_XSTATUS)) - return 0; // contact does not have xstatus - - // delay is disabled only if fired from dialog - if (!CheckContactCapabilities(hContact, CAPF_XTRAZ) && bAllowDelay) - return 0; // Contact does not support xtraz, do not request details - - struct rates_xstatus_request : public rates_queue_item - { - protected: - virtual rates_queue_item* copyItem(rates_queue_item *aDest = nullptr) - { - rates_xstatus_request *pDest = (rates_xstatus_request*)aDest; - if (!pDest) - pDest = new rates_xstatus_request(ppro, wGroup); - - pDest->bForced = bForced; - return rates_queue_item::copyItem(pDest); - }; - public: - rates_xstatus_request(CIcqProto *ppro, WORD wGroup) : rates_queue_item(ppro, wGroup) {}; - virtual ~rates_xstatus_request() {}; - - virtual void execute() - { - dwCookie = ppro->sendXStatusDetailsRequest(hContact, bForced); - }; - - BOOL bForced; - DWORD dwCookie; - }; - - WORD wGroup; - { - mir_cslock l(m_ratesMutex); - wGroup = m_rates->getGroupFromSNAC(ICQ_MSG_FAMILY, ICQ_MSG_SRV_SEND); - } - - rates_xstatus_request rr(this, wGroup); - rr.bForced = !bAllowDelay; - rr.hContact = hContact; - - // delay at least one sec if allowed - if (!handleRateItem(&rr, RQT_REQUEST, 1000, bAllowDelay)) - return rr.dwCookie; - - return -1; // delayed -} - -static HANDLE LoadXStatusIconLibrary(wchar_t *path, const wchar_t *sub) -{ - wchar_t* p = wcsrchr(path, '\\'); - HANDLE hLib; - - mir_wstrcpy(p, sub); - mir_wstrcat(p, L"\\xstatus_ICQ.dll"); - if (hLib = LoadLibrary(path)) - return hLib; - mir_wstrcpy(p, sub); - mir_wstrcat(p, L"\\xstatus_icons.dll"); - if (hLib = LoadLibrary(path)) - return hLib; - mir_wstrcpy(p, L"\\"); - return hLib; -} - -static wchar_t* InitXStatusIconLibrary(wchar_t *buf, size_t buf_size) -{ - wchar_t path[2 * MAX_PATH]; - HMODULE hXStatusIconsDLL; - - // get miranda's exe path - GetModuleFileName(nullptr, path, MAX_PATH); - - hXStatusIconsDLL = (HMODULE)LoadXStatusIconLibrary(path, L"\\Icons"); - if (!hXStatusIconsDLL) // TODO: add "Custom Folders" support - hXStatusIconsDLL = (HMODULE)LoadXStatusIconLibrary(path, L"\\Plugins"); - - if (hXStatusIconsDLL) { - null_strcpy(buf, path, buf_size - 1); - - char ident[MAX_PATH]; - if (LoadStringA(hXStatusIconsDLL, IDS_IDENTIFY, ident, sizeof(ident)) == 0 || mir_strcmp(ident, "# Custom Status Icons #")) - *buf = 0; - - FreeLibrary(hXStatusIconsDLL); - } - else *buf = 0; - - return buf; -} - -HICON CIcqProto::getXStatusIcon(int bStatus, UINT flags) -{ - HICON icon = nullptr; - - if (bStatus > 0 && bStatus <= XSTATUS_COUNT) - icon = IcoLib_GetIconByHandle(hXStatusIcons[bStatus - 1], (flags & LR_BIGICON) != 0); - - return (flags & LR_SHARED || !icon) ? icon : CopyIcon(icon); -} - -void setContactExtraIcon(MCONTACT hContact, int xstatus) -{ - ExtraIcon_SetIcon(hExtraXStatus, hContact, (xstatus > 0) ? hXStatusIcons[xstatus - 1] : nullptr); -} - -#define NULLCAP {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} - -capstr capXStatus[XSTATUS_COUNT] = { - {0x01, 0xD8, 0xD7, 0xEE, 0xAC, 0x3B, 0x49, 0x2A, 0xA5, 0x8D, 0xD3, 0xD8, 0x77, 0xE6, 0x6B, 0x92}, - {0x5A, 0x58, 0x1E, 0xA1, 0xE5, 0x80, 0x43, 0x0C, 0xA0, 0x6F, 0x61, 0x22, 0x98, 0xB7, 0xE4, 0xC7}, - {0x83, 0xC9, 0xB7, 0x8E, 0x77, 0xE7, 0x43, 0x78, 0xB2, 0xC5, 0xFB, 0x6C, 0xFC, 0xC3, 0x5B, 0xEC}, - {0xE6, 0x01, 0xE4, 0x1C, 0x33, 0x73, 0x4B, 0xD1, 0xBC, 0x06, 0x81, 0x1D, 0x6C, 0x32, 0x3D, 0x81}, - {0x8C, 0x50, 0xDB, 0xAE, 0x81, 0xED, 0x47, 0x86, 0xAC, 0xCA, 0x16, 0xCC, 0x32, 0x13, 0xC7, 0xB7}, - {0x3F, 0xB0, 0xBD, 0x36, 0xAF, 0x3B, 0x4A, 0x60, 0x9E, 0xEF, 0xCF, 0x19, 0x0F, 0x6A, 0x5A, 0x7F}, - {0xF8, 0xE8, 0xD7, 0xB2, 0x82, 0xC4, 0x41, 0x42, 0x90, 0xF8, 0x10, 0xC6, 0xCE, 0x0A, 0x89, 0xA6}, - {0x80, 0x53, 0x7D, 0xE2, 0xA4, 0x67, 0x4A, 0x76, 0xB3, 0x54, 0x6D, 0xFD, 0x07, 0x5F, 0x5E, 0xC6}, - {0xF1, 0x8A, 0xB5, 0x2E, 0xDC, 0x57, 0x49, 0x1D, 0x99, 0xDC, 0x64, 0x44, 0x50, 0x24, 0x57, 0xAF}, - {0x1B, 0x78, 0xAE, 0x31, 0xFA, 0x0B, 0x4D, 0x38, 0x93, 0xD1, 0x99, 0x7E, 0xEE, 0xAF, 0xB2, 0x18}, - {0x61, 0xBE, 0xE0, 0xDD, 0x8B, 0xDD, 0x47, 0x5D, 0x8D, 0xEE, 0x5F, 0x4B, 0xAA, 0xCF, 0x19, 0xA7}, - {0x48, 0x8E, 0x14, 0x89, 0x8A, 0xCA, 0x4A, 0x08, 0x82, 0xAA, 0x77, 0xCE, 0x7A, 0x16, 0x52, 0x08}, - {0x10, 0x7A, 0x9A, 0x18, 0x12, 0x32, 0x4D, 0xA4, 0xB6, 0xCD, 0x08, 0x79, 0xDB, 0x78, 0x0F, 0x09}, - {0x6F, 0x49, 0x30, 0x98, 0x4F, 0x7C, 0x4A, 0xFF, 0xA2, 0x76, 0x34, 0xA0, 0x3B, 0xCE, 0xAE, 0xA7}, - {0x12, 0x92, 0xE5, 0x50, 0x1B, 0x64, 0x4F, 0x66, 0xB2, 0x06, 0xB2, 0x9A, 0xF3, 0x78, 0xE4, 0x8D}, - {0xD4, 0xA6, 0x11, 0xD0, 0x8F, 0x01, 0x4E, 0xC0, 0x92, 0x23, 0xC5, 0xB6, 0xBE, 0xC6, 0xCC, 0xF0}, - {0x60, 0x9D, 0x52, 0xF8, 0xA2, 0x9A, 0x49, 0xA6, 0xB2, 0xA0, 0x25, 0x24, 0xC5, 0xE9, 0xD2, 0x60}, - {0x63, 0x62, 0x73, 0x37, 0xA0, 0x3F, 0x49, 0xFF, 0x80, 0xE5, 0xF7, 0x09, 0xCD, 0xE0, 0xA4, 0xEE}, - {0x1F, 0x7A, 0x40, 0x71, 0xBF, 0x3B, 0x4E, 0x60, 0xBC, 0x32, 0x4C, 0x57, 0x87, 0xB0, 0x4C, 0xF1}, - {0x78, 0x5E, 0x8C, 0x48, 0x40, 0xD3, 0x4C, 0x65, 0x88, 0x6F, 0x04, 0xCF, 0x3F, 0x3F, 0x43, 0xDF}, - {0xA6, 0xED, 0x55, 0x7E, 0x6B, 0xF7, 0x44, 0xD4, 0xA5, 0xD4, 0xD2, 0xE7, 0xD9, 0x5C, 0xE8, 0x1F}, - {0x12, 0xD0, 0x7E, 0x3E, 0xF8, 0x85, 0x48, 0x9E, 0x8E, 0x97, 0xA7, 0x2A, 0x65, 0x51, 0xE5, 0x8D}, - {0xBA, 0x74, 0xDB, 0x3E, 0x9E, 0x24, 0x43, 0x4B, 0x87, 0xB6, 0x2F, 0x6B, 0x8D, 0xFE, 0xE5, 0x0F}, - {0x63, 0x4F, 0x6B, 0xD8, 0xAD, 0xD2, 0x4A, 0xA1, 0xAA, 0xB9, 0x11, 0x5B, 0xC2, 0x6D, 0x05, 0xA1}, - {0x2C, 0xE0, 0xE4, 0xE5, 0x7C, 0x64, 0x43, 0x70, 0x9C, 0x3A, 0x7A, 0x1C, 0xE8, 0x78, 0xA7, 0xDC}, - {0x10, 0x11, 0x17, 0xC9, 0xA3, 0xB0, 0x40, 0xF9, 0x81, 0xAC, 0x49, 0xE1, 0x59, 0xFB, 0xD5, 0xD4}, - {0x16, 0x0C, 0x60, 0xBB, 0xDD, 0x44, 0x43, 0xF3, 0x91, 0x40, 0x05, 0x0F, 0x00, 0xE6, 0xC0, 0x09}, - {0x64, 0x43, 0xC6, 0xAF, 0x22, 0x60, 0x45, 0x17, 0xB5, 0x8C, 0xD7, 0xDF, 0x8E, 0x29, 0x03, 0x52}, - {0x16, 0xF5, 0xB7, 0x6F, 0xA9, 0xD2, 0x40, 0x35, 0x8C, 0xC5, 0xC0, 0x84, 0x70, 0x3C, 0x98, 0xFA}, - {0x63, 0x14, 0x36, 0xff, 0x3f, 0x8a, 0x40, 0xd0, 0xa5, 0xcb, 0x7b, 0x66, 0xe0, 0x51, 0xb3, 0x64}, - {0xb7, 0x08, 0x67, 0xf5, 0x38, 0x25, 0x43, 0x27, 0xa1, 0xff, 0xcf, 0x4c, 0xc1, 0x93, 0x97, 0x97}, - {0xdd, 0xcf, 0x0e, 0xa9, 0x71, 0x95, 0x40, 0x48, 0xa9, 0xc6, 0x41, 0x32, 0x06, 0xd6, 0xf2, 0x80}, - NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, - NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, - NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, - NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, - NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, NULLCAP, - NULLCAP, NULLCAP, NULLCAP, NULLCAP }; - -const char *nameXStatus[XSTATUS_COUNT] = { - LPGEN("Angry"), // 23 - LPGEN("Taking a bath"), // 1 - LPGEN("Tired"), // 2 - LPGEN("Birthday"), // 3 - LPGEN("Drinking beer"), // 4 - LPGEN("Thinking"), // 5 - LPGEN("Eating"), // 80 - LPGEN("Watching TV"), // 7 - LPGEN("Meeting"), // 8 - LPGEN("Coffee"), // 9 - LPGEN("Listening to music"),// 10 - LPGEN("Business"), // 11 - LPGEN("Shooting"), // 12 - LPGEN("Having fun"), // 13 - LPGEN("On the phone"), // 14 - LPGEN("Gaming"), // 15 - LPGEN("Studying"), // 16 - LPGEN("Shopping"), // 0 - LPGEN("Feeling sick"), // 17 - LPGEN("Sleeping"), // 18 - LPGEN("Surfing"), // 19 - LPGEN("Internet"), // 20 - LPGEN("Working"), // 21 - LPGEN("Typing"), // 22 - LPGEN("Picnic"), // 66 - LPGEN("Cooking"), - LPGEN("Smoking"), - LPGEN("I'm high"), - LPGEN("On WC"), // 68 - LPGEN("To be or not to be"),// 77 - LPGEN("Watching pro7 on TV"), - LPGEN("Love"), // 61 - LPGEN("Hot Dog"), //6 - LPGEN("Rough"), //24 - LPGEN("Rock On"), //25 - LPGEN("Baby"), //26 - LPGEN("Soccer"), //27 - LPGEN("Pirate"), //28 - LPGEN("Cyclop"), //29 - LPGEN("Monkey"), //30 - LPGEN("Birdie"), //31 - LPGEN("Cool"), //32 - LPGEN("Evil"), //33 - LPGEN("Alien"), //34 - LPGEN("Scooter"), //35 - LPGEN("Mask"), //36 - LPGEN("Money"), //37 - LPGEN("Pilot"), //38 - LPGEN("Afro"), //39 - LPGEN("St. Patrick"), //40 - LPGEN("Headmaster"), //41 - LPGEN("Lips"), //42 - LPGEN("Ice-Cream"), //43 - LPGEN("Pink Lady"), //44 - LPGEN("Up yours"), //45 - LPGEN("Laughing"), //46 - LPGEN("Dog"), //47 - LPGEN("Candy"), //48 - LPGEN("Crazy Professor"),//50 - LPGEN("Ninja"), //51 - LPGEN("Cocktail"), //52 - LPGEN("Punch"), //53 - LPGEN("Donut"), //54 - LPGEN("Feeling Good"), //55 - LPGEN("Lollypop"), //56 - LPGEN("Oink Oink"), //57 - LPGEN("Kitty"), //58 - LPGEN("Sumo"), //59 - LPGEN("Broken hearted"),//60 - LPGEN("Free for chat"), //62 - LPGEN("@home"), //63 - LPGEN("@work"), //64 - LPGEN("Strawberry"), //65 - LPGEN("Angel"), //67 - LPGEN("Pizza"), //69 - LPGEN("Snoring"), //70 - LPGEN("On my mobile"), //71 - LPGEN("Depressed"), //72 - LPGEN("Beetle"), //73 - LPGEN("Double Rainbow"),//74 - LPGEN("Basketball"), //75 - LPGEN("Cupid shot me"), //76 - LPGEN("Celebrating"), //78 - LPGEN("Sushi"), //79 - LPGEN("Playing"), //81 - LPGEN("Writing") //84 -}; - -const int moodXStatus[XSTATUS_COUNT] = { - 23, - 1, - 2, - 3, - 4, - 5, - 80, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 0, - 17, - 18, - 19, - 20, - 21, - 22, - 66, - -1, - -1, - -1, - 68, - 77, - -1, - 61, - 6, - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 31, - 32, - 33, - 34, - 35, - 36, - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 50, - 51, - 52, - 53, - 54, - 55, - 56, - 57, - 58, - 59, - 60, - 62, - 63, - 64, - 65, - 67, - 69, - 70, - 71, - 72, - 73, - 74, - 75, - 76, - 78, - 79, - 81, - 84 }; - -void CIcqProto::handleXStatusCaps(DWORD dwUIN, char *szUID, MCONTACT hContact, BYTE *caps, int capsize, char *moods, int moodsize) -{ - int bChanged = FALSE; - int nCustomStatusID = 0, nMoodID = 0; - - if (!m_bXStatusEnabled && !m_bMoodsEnabled) { - ClearContactCapabilities(hContact, CAPF_STATUS_MOOD | CAPF_XSTATUS); - return; - } - int nOldXStatusID = getContactXStatus(hContact); - - if (m_bMoodsEnabled) { - // process custom statuses (moods) from ICQ6 - if (moods) { - if (moodsize > 0) - if (moodsize >= 32) - moods[32] = '\0'; - - for (int i = 0; i < XSTATUS_COUNT; i++) { - char szMoodId[32], szMoodData[32]; - - null_strcpy(szMoodData, moods, moodsize); - - if (moodXStatus[i] == -1) continue; - mir_snprintf(szMoodId, "0icqmood%d", moodXStatus[i]); - if (!mir_strcmp(szMoodId, szMoodData)) { - BYTE bXStatusId = (BYTE)(i + 1); - char str[MAX_PATH]; - - SetContactCapabilities(hContact, CAPF_STATUS_MOOD); - - // only write default name when it is really needed, i.e. on Custom Status change - if (nOldXStatusID != bXStatusId) { - setByte(hContact, DBSETTING_XSTATUS_ID, bXStatusId); - db_set_utf(hContact, m_szModuleName, DBSETTING_XSTATUS_NAME, ICQTranslateUtfStatic(nameXStatus[i], str, MAX_PATH)); - delSetting(hContact, DBSETTING_XSTATUS_MSG); - - debugLogA("%s changed mood to %s.", strUID(dwUIN, szUID), ICQTranslateUtfStatic(nameXStatus[i], str, MAX_PATH)); - bChanged = TRUE; - } - - // cannot retrieve mood details here - need to be processed with new user details - nMoodID = bXStatusId; - - break; - } - } - - if (nMoodID == 0 && moods) - ClearContactCapabilities(hContact, CAPF_STATUS_MOOD); - } - } - - if (m_bXStatusEnabled) { - // detect custom status capabilities - if (caps) { - if (capsize > 0) - for (int i = 0; i < XSTATUS_COUNT; i++) { - if (MatchCapability(caps, capsize, (const capstr*)capXStatus[i], BINARY_CAP_SIZE)) { - BYTE bXStatusId = (BYTE)(i + 1); - char str[MAX_PATH]; - - SetContactCapabilities(hContact, CAPF_XSTATUS); - - // only write default name when it is really needed, i.e. on Custom Status change - if (nMoodID == 0 && nOldXStatusID != bXStatusId) { - setByte(hContact, DBSETTING_XSTATUS_ID, bXStatusId); - db_set_utf(hContact, m_szModuleName, DBSETTING_XSTATUS_NAME, ICQTranslateUtfStatic(nameXStatus[i], str, MAX_PATH)); - delSetting(hContact, DBSETTING_XSTATUS_MSG); - - debugLogA("%s changed custom status to %s.", strUID(dwUIN, szUID), ICQTranslateUtfStatic(nameXStatus[i], str, MAX_PATH)); - bChanged = TRUE; - } - - if (getByte("XStatusAuto", DEFAULT_XSTATUS_AUTO)) - requestXStatusDetails(hContact, TRUE); - - nCustomStatusID = bXStatusId; - break; - } - } - - if (nCustomStatusID == 0) - ClearContactCapabilities(hContact, CAPF_XSTATUS); - } - } - - if (nCustomStatusID != 0 && nMoodID != 0 && nCustomStatusID != nMoodID) - debugLogA("Warning: Diverse custom statuses detected, using mood status."); - - if ((nCustomStatusID == 0 && (caps || !m_bXStatusEnabled)) && (nMoodID == 0 && (moods || !m_bMoodsEnabled))) { - if (getByte(hContact, DBSETTING_XSTATUS_ID, -1) != -1) - bChanged = TRUE; - delSetting(hContact, DBSETTING_XSTATUS_ID); - delSetting(hContact, DBSETTING_XSTATUS_NAME); - delSetting(hContact, DBSETTING_XSTATUS_MSG); - } - - if (m_bXStatusEnabled != 10 && m_bMoodsEnabled != 10) - setContactExtraIcon(hContact, nMoodID ? nMoodID : (moods ? 0 : (nCustomStatusID ? nCustomStatusID : nOldXStatusID))); -} - - -void CIcqProto::updateServerCustomStatus(int fullUpdate) -{ - BYTE bXStatus = getContactXStatus(NULL); - - // update client capabilities - if (fullUpdate) { - if (m_bXStatusEnabled) - setUserInfo(); - - char szMoodData[32]; - - // prepare mood id - if (m_bMoodsEnabled && bXStatus && moodXStatus[bXStatus - 1] != -1) - mir_snprintf(szMoodData, "0icqmood%d", moodXStatus[bXStatus - 1]); - else - szMoodData[0] = '\0'; - - SetStatusMood(szMoodData, 1500); - } - - char *szStatusNote = nullptr; - - // use custom status message as status note - if (bXStatus && (m_bXStatusEnabled || m_bMoodsEnabled)) - szStatusNote = getSettingStringUtf(NULL, DBSETTING_XSTATUS_MSG, ""); - // retrieve standard status message (e.g. custom status set to none) - else { - char **pszMsg = MirandaStatusToAwayMsg(m_iStatus); - { - mir_cslock l(m_modeMsgsMutex); - if (pszMsg) - szStatusNote = null_strdup(*pszMsg); - } - - // no default status message, set empty - if (!szStatusNote) - szStatusNote = null_strdup(""); - } - - if (szStatusNote) - SetStatusNote(szStatusNote, 1500, FALSE); - - SAFE_FREE(&szStatusNote); -} - -static LRESULT CALLBACK MessageEditSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) { - case WM_CHAR: - if (wParam == '\n' && GetKeyState(VK_CONTROL) & 0x8000) { - PostMessage(GetParent(hwnd), WM_COMMAND, IDOK, 0); - return 0; - } - if (wParam == 1 && GetKeyState(VK_CONTROL) & 0x8000) { // ctrl-a - SendMessage(hwnd, EM_SETSEL, 0, -1); - return 0; - } - if (wParam == 23 && GetKeyState(VK_CONTROL) & 0x8000) { // ctrl-w - SendMessage(GetParent(hwnd), WM_CLOSE, 0, 0); - return 0; - } - if (wParam == 127 && GetKeyState(VK_CONTROL) & 0x8000) { // ctrl-backspace - DWORD start, end; - SendMessage(hwnd, EM_GETSEL, (WPARAM)&end, (LPARAM)(PDWORD)NULL); - SendMessage(hwnd, WM_KEYDOWN, VK_LEFT, 0); - SendMessage(hwnd, EM_GETSEL, (WPARAM)&start, (LPARAM)(PDWORD)NULL); - WCHAR *text = GetWindowTextUcs(hwnd); - memmove(text + start, text + end, sizeof(WCHAR) * (mir_wstrlen(text) + 1 - end)); - SetWindowTextUcs(hwnd, text); - SAFE_FREE(&text); - SendMessage(hwnd, EM_SETSEL, start, start); - SendMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(hwnd), EN_CHANGE), (LPARAM)hwnd); - return 0; - } - break; - } - return mir_callNextSubclass(hwnd, MessageEditSubclassProc, msg, wParam, lParam); -} - -struct SetXStatusData -{ - CIcqProto* ppro; - BYTE bAction; - BYTE bXStatus; - MCONTACT hContact; - HANDLE hEvent; - DWORD iEvent; - int countdown; - char* okButtonFormat; -}; - -struct InitXStatusData -{ - CIcqProto* ppro; - BYTE bAction; - BYTE bXStatus; - char* szXStatusName; - char* szXStatusMsg; - MCONTACT hContact; -}; - -#define HM_PROTOACK (WM_USER+10) -static INT_PTR CALLBACK SetXStatusDlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - SetXStatusData *dat = (SetXStatusData*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - char str[MAX_PATH]; - - switch (message) { - case HM_PROTOACK: - { - ACKDATA *ack = (ACKDATA*)lParam; - if (ack->type != ICQACKTYPE_XSTATUS_RESPONSE) break; - if (ack->hContact != dat->hContact) break; - if ((UINT_PTR)ack->hProcess != dat->iEvent) break; - - ShowDlgItem(hwndDlg, IDC_RETRXSTATUS, SW_HIDE); - ShowDlgItem(hwndDlg, IDC_XMSG, SW_SHOW); - ShowDlgItem(hwndDlg, IDC_XTITLE, SW_SHOW); - SetDlgItemText(hwndDlg, IDOK, TranslateT("Close")); - UnhookEvent(dat->hEvent); dat->hEvent = nullptr; - char *szText = dat->ppro->getSettingStringUtf(dat->hContact, DBSETTING_XSTATUS_NAME, ""); - SetDlgItemTextUtf(hwndDlg, IDC_XTITLE, szText); - SAFE_FREE(&szText); - szText = dat->ppro->getSettingStringUtf(dat->hContact, DBSETTING_XSTATUS_MSG, ""); - SetDlgItemTextUtf(hwndDlg, IDC_XMSG, szText); - SAFE_FREE(&szText); - } - break; - - case WM_INITDIALOG: - { - InitXStatusData *init = (InitXStatusData*)lParam; - - TranslateDialogDefault(hwndDlg); - dat = (SetXStatusData*)SAFE_MALLOC(sizeof(SetXStatusData)); - dat->ppro = init->ppro; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat); - dat->bAction = init->bAction; - - if (!init->bAction) { // set our xStatus - dat->bXStatus = init->bXStatus; - SendDlgItemMessage(hwndDlg, IDC_XMSG, EM_LIMITTEXT, 1024, 0); - mir_subclassWindow(GetDlgItem(hwndDlg, IDC_XMSG), MessageEditSubclassProc); - SetDlgItemTextUtf(hwndDlg, IDC_XMSG, init->szXStatusMsg); - - if (dat->ppro->m_bXStatusEnabled) { // custom status enabled, prepare title edit - SendDlgItemMessage(hwndDlg, IDC_XTITLE, EM_LIMITTEXT, 256, 0); - mir_subclassWindow(GetDlgItem(hwndDlg, IDC_XTITLE), MessageEditSubclassProc); - SetDlgItemTextUtf(hwndDlg, IDC_XTITLE, init->szXStatusName); - } - else { // only moods enabled, hide title, resize message edit control - ShowDlgItem(hwndDlg, IDC_XTITLE_STATIC, SW_HIDE); - ShowDlgItem(hwndDlg, IDC_XTITLE, SW_HIDE); - MoveDlgItem(hwndDlg, IDC_XMSG_STATIC, 5, 0, 179, 8); - MoveDlgItem(hwndDlg, IDC_XMSG, 5, 9, 179, 65); - } - - dat->okButtonFormat = GetDlgItemTextUtf(hwndDlg, IDOK); - dat->countdown = 5; - SendMessage(hwndDlg, WM_TIMER, 0, 0); - SetTimer(hwndDlg, 1, 1000, nullptr); - } - else { // retrieve contact's xStatus - dat->hContact = init->hContact; - dat->bXStatus = dat->ppro->getContactXStatus(dat->hContact); - dat->okButtonFormat = nullptr; - SendDlgItemMessage(hwndDlg, IDC_XTITLE, EM_SETREADONLY, 1, 0); - SendDlgItemMessage(hwndDlg, IDC_XMSG, EM_SETREADONLY, 1, 0); - - if (dat->ppro->CheckContactCapabilities(dat->hContact, CAPF_XSTATUS) && !dat->ppro->getByte("XStatusAuto", DEFAULT_XSTATUS_AUTO)) { - SetDlgItemText(hwndDlg, IDOK, TranslateT("Cancel")); - dat->hEvent = HookEventMessage(ME_PROTO_ACK, hwndDlg, HM_PROTOACK); - ShowDlgItem(hwndDlg, IDC_RETRXSTATUS, SW_SHOW); - ShowDlgItem(hwndDlg, IDC_XMSG, SW_HIDE); - ShowDlgItem(hwndDlg, IDC_XTITLE, SW_HIDE); - dat->iEvent = dat->ppro->requestXStatusDetails(dat->hContact, FALSE); - } - else { - SetDlgItemText(hwndDlg, IDOK, TranslateT("Close")); - dat->hEvent = nullptr; - char *szText = dat->ppro->getSettingStringUtf(dat->hContact, DBSETTING_XSTATUS_NAME, ""); - SetDlgItemTextUtf(hwndDlg, IDC_XTITLE, szText); - SAFE_FREE(&szText); - - // only for clients supporting just moods and not custom status - if (dat->ppro->CheckContactCapabilities(dat->hContact, CAPF_STATUS_MOOD) && !dat->ppro->CheckContactCapabilities(dat->hContact, CAPF_XSTATUS)) { - szText = dat->ppro->getSettingStringUtf(dat->hContact, DBSETTING_STATUS_NOTE, ""); - // hide title, resize message edit control - ShowDlgItem(hwndDlg, IDC_XTITLE_STATIC, SW_HIDE); - ShowDlgItem(hwndDlg, IDC_XTITLE, SW_HIDE); - MoveDlgItem(hwndDlg, IDC_XMSG_STATIC, 5, 0, 179, 8); - MoveDlgItem(hwndDlg, IDC_XMSG, 5, 9, 179, 65); - } - else szText = dat->ppro->getSettingStringUtf(dat->hContact, DBSETTING_XSTATUS_MSG, ""); - - SetDlgItemTextUtf(hwndDlg, IDC_XMSG, szText); - SAFE_FREE(&szText); - } - } - - if (dat->bXStatus) { - SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)dat->ppro->getXStatusIcon(dat->bXStatus, LR_SHARED | LR_BIGICON)); - SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)dat->ppro->getXStatusIcon(dat->bXStatus, LR_SHARED)); - } - - char buf[MAX_PATH]; - char *format = GetWindowTextUtf(hwndDlg); - - mir_snprintf(str, format, dat->bXStatus ? ICQTranslateUtfStatic(nameXStatus[dat->bXStatus - 1], buf, MAX_PATH) : ""); - SetWindowTextUtf(hwndDlg, str); - SAFE_FREE(&format); - } - return TRUE; - - case WM_TIMER: - if (dat->countdown == -1) { - DestroyWindow(hwndDlg); - break; - } - - mir_snprintf(str, dat->okButtonFormat, dat->countdown); - SetDlgItemTextUtf(hwndDlg, IDOK, str); - dat->countdown--; - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDOK: - DestroyWindow(hwndDlg); - break; - - case IDC_XTITLE: - case IDC_XMSG: - if (!dat->bAction) { // set our xStatus - KillTimer(hwndDlg, 1); - SetDlgItemText(hwndDlg, IDOK, TranslateT("OK")); - } - } - break; - - case WM_DESTROY: - if (!dat->bAction) { // set our xStatus - char szSetting[64]; - - dat->ppro->setByte(DBSETTING_XSTATUS_ID, dat->bXStatus); - char *szValue = GetDlgItemTextUtf(hwndDlg, IDC_XMSG); - mir_snprintf(szSetting, "XStatus%dMsg", dat->bXStatus); - db_set_utf(NULL, dat->ppro->m_szModuleName, szSetting, szValue); - db_set_utf(NULL, dat->ppro->m_szModuleName, DBSETTING_XSTATUS_MSG, szValue); - SAFE_FREE(&szValue); - - if (dat->ppro->m_bXStatusEnabled) { - szValue = GetDlgItemTextUtf(hwndDlg, IDC_XTITLE); - mir_snprintf(szSetting, "XStatus%dName", dat->bXStatus); - db_set_utf(NULL, dat->ppro->m_szModuleName, szSetting, szValue); - db_set_utf(NULL, dat->ppro->m_szModuleName, DBSETTING_XSTATUS_NAME, szValue); - SAFE_FREE(&szValue); - - if (dat->bXStatus) - Window_FreeIcon_IcoLib(hwndDlg); - } - dat->ppro->updateServerCustomStatus(TRUE); - } - if (dat->hEvent) UnhookEvent(dat->hEvent); - SAFE_FREE(&dat->okButtonFormat); - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0); - SAFE_FREE((void**)&dat); - break; - - case WM_CLOSE: - DestroyWindow(hwndDlg); - break; - } - return FALSE; -} - -void CIcqProto::setXStatusEx(BYTE bXStatus, BYTE bQuiet) -{ - BYTE bOldXStatus = getByte(DBSETTING_XSTATUS_ID, 0); - - if (!m_bHideXStatusUI) { - if (bOldXStatus <= XSTATUS_COUNT) - Menu_ModifyItem(hXStatusItems[bOldXStatus], nullptr, INVALID_HANDLE_VALUE, 0); - - Menu_ModifyItem(hXStatusItems[bXStatus], nullptr, INVALID_HANDLE_VALUE, CMIF_CHECKED); - } - - if (bXStatus) { - char szSetting[64]; - char str[MAX_PATH]; - char *szName = nullptr, *szMsg = nullptr; - - if (m_bXStatusEnabled) { - mir_snprintf(szSetting, "XStatus%dName", bXStatus); - szName = getSettingStringUtf(NULL, szSetting, ICQTranslateUtfStatic(nameXStatus[bXStatus - 1], str, MAX_PATH)); - } - mir_snprintf(szSetting, "XStatus%dMsg", bXStatus); - szMsg = getSettingStringUtf(NULL, szSetting, ""); - - mir_snprintf(szSetting, "XStatus%dStat", bXStatus); - if (!bQuiet && !getByte(szSetting, 0)) { - InitXStatusData init; - init.ppro = this; - init.bAction = 0; // set - init.bXStatus = bXStatus; - init.szXStatusName = szName; - init.szXStatusMsg = szMsg; - CreateDialogParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_SETXSTATUS), nullptr, SetXStatusDlgProc, (LPARAM)&init); - } - else { - setByte(DBSETTING_XSTATUS_ID, bXStatus); - if (m_bXStatusEnabled) - db_set_utf(NULL, m_szModuleName, DBSETTING_XSTATUS_NAME, szName); - db_set_utf(NULL, m_szModuleName, DBSETTING_XSTATUS_MSG, szMsg); - - updateServerCustomStatus(TRUE); - } - SAFE_FREE(&szName); - SAFE_FREE(&szMsg); - } - else { - setByte(DBSETTING_XSTATUS_ID, bXStatus); - delSetting(DBSETTING_XSTATUS_NAME); - delSetting(DBSETTING_XSTATUS_MSG); - - updateServerCustomStatus(TRUE); - } -} - -INT_PTR CIcqProto::menuXStatus(WPARAM, LPARAM, LPARAM fParam) -{ - setXStatusEx((BYTE)fParam, 0); - return 0; -} - -void CIcqProto::InitXStatusItems(BOOL bAllowStatus) -{ - BYTE bXStatus = getContactXStatus(NULL); - - if (!m_bXStatusEnabled && !m_bMoodsEnabled) - return; - - if (!bAllowStatus) - return; - - // Custom Status UI is disabled, no need to continue items' init - if (m_bHideXStatusUI || m_bHideXStatusMenu) - return; - - HGENMENU hRoot; - { - wchar_t szItem[MAX_PATH + 64]; - mir_snwprintf(szItem, TranslateT("%s Custom Status"), m_tszUserName); - - CMenuItem mi(&g_plugin); - mi.root = Menu_GetProtocolMenu(m_szModuleName); - mi.name.w = szItem; - mi.position = 10001; - hRoot = Menu_AddStatusMenuItem(&mi, m_szModuleName); - } - - CMenuItem mi(&g_plugin); - mi.position = 2000040000; - mi.root = hRoot; - - int bXStatusMenuBuilt = 0; - for (int i = 0; i <= XSTATUS_COUNT; i++) { - char srvFce[MAX_PATH + 64]; - mir_snprintf(srvFce, "/menuXStatus%d", i); - mi.position++; - - if (!i) - bXStatusMenuBuilt = ProtoServiceExists(m_szModuleName, srvFce); - - if (!bXStatusMenuBuilt) - CreateProtoServiceParam(srvFce, &CIcqProto::menuXStatus, i); - - mi.flags = (bXStatus == i ? CMIF_CHECKED : 0); - mi.hIcolibItem = i ? hXStatusIcons[i - 1] : nullptr; - mi.name.a = i ? (char*)nameXStatus[i - 1] : (char *)LPGEN("None"); - mi.pszService = srvFce; - - hXStatusItems[i] = Menu_AddStatusMenuItem(&mi, m_szModuleName); - Menu_ShowItem(hXStatusItems[i], !(m_bHideXStatusUI || m_bHideXStatusMenu)); - } -} - -void InitXStatusIcons() -{ - wchar_t lib[2 * MAX_PATH] = { 0 }; - - SKINICONDESC sid = {}; - sid.section.a = "Protocols/" ICQ_PROTOCOL_NAME "/" LPGEN("Custom Status"); - sid.flags = SIDF_PATH_UNICODE; - sid.defaultFile.w = InitXStatusIconLibrary(lib, _countof(lib)); - - for (int i = 0; i < XSTATUS_COUNT; i++) { - char szTemp[100]; - mir_snprintf(szTemp, "icq_xstatus%d", i); - sid.pszName = szTemp; - sid.description.a = (LPSTR)nameXStatus[i]; - sid.iDefaultIndex = -(IDI_XSTATUS1 + i); - hXStatusIcons[i] = g_plugin.addIcon(&sid); - } - - // initialize arrays for CList custom status icons - memset(bXStatusCListIconsValid, 0, sizeof(bXStatusCListIconsValid)); - memset(hXStatusCListIcons, -1, sizeof(hXStatusCListIcons)); -} - -INT_PTR CIcqProto::ShowXStatusDetails(WPARAM hContact, LPARAM) -{ - InitXStatusData init; - init.ppro = this; - init.bAction = 1; // retrieve - init.hContact = hContact; - CreateDialogParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_SETXSTATUS), nullptr, SetXStatusDlgProc, (LPARAM)&init); - - return 0; -} - -INT_PTR CIcqProto::SetXStatusEx(WPARAM, LPARAM lParam) -{ - CUSTOM_STATUS *pData = (CUSTOM_STATUS*)lParam; - - if (!m_bXStatusEnabled && !m_bMoodsEnabled) return 1; - - if (pData->cbSize < sizeof(CUSTOM_STATUS)) return 1; // Failure - - if (pData->flags & CSSF_MASK_STATUS) { // set custom status - int status = *pData->status; - - if (status >= 0 && status <= XSTATUS_COUNT) - setXStatusEx((BYTE)status, 1); - else - return 1; // Failure - } - - if (pData->flags & (CSSF_MASK_NAME | CSSF_MASK_MESSAGE)) { - BYTE status = getContactXStatus(NULL); - - if (!status) return 1; // Failure - - if (m_bXStatusEnabled && (pData->flags & CSSF_MASK_NAME)) { // set custom status name - if (pData->flags & CSSF_UNICODE) - setWString(DBSETTING_XSTATUS_NAME, pData->pwszName); - else - setString(DBSETTING_XSTATUS_NAME, pData->pszName); - } - if (pData->flags & CSSF_MASK_MESSAGE) { // set custom status message - if (pData->flags & CSSF_UNICODE) - setWString(DBSETTING_XSTATUS_MSG, pData->pwszMessage); - else - setString(DBSETTING_XSTATUS_MSG, pData->pszMessage); - - // update status note if used for custom status message - updateServerCustomStatus(FALSE); - } - } - - // hide menu items + contact menu item - if (pData->flags & CSSF_DISABLE_UI) - m_bHideXStatusUI = (*pData->wParam) ? 0 : 1; - - // hide menu items only - if (pData->flags & CSSF_DISABLE_MENU) - m_bHideXStatusMenu = (*pData->wParam) ? 0 : 1; - - return 0; // Success -} - -INT_PTR CIcqProto::GetXStatusEx(WPARAM hContact, LPARAM lParam) -{ - if (!m_bXStatusEnabled && !m_bMoodsEnabled) - return 1; - - CUSTOM_STATUS *pData = (CUSTOM_STATUS*)lParam; - if (pData->cbSize < sizeof(CUSTOM_STATUS)) - return 1; // Failure - - // fill status member - if (pData->flags & CSSF_MASK_STATUS) - *pData->status = getContactXStatus(hContact); - - // fill status name member - if (pData->flags & CSSF_MASK_NAME) { - if (pData->flags & CSSF_DEFAULT_NAME) { - int status = (pData->wParam == nullptr) ? getContactXStatus(hContact) : *pData->wParam; - if (status < 1 || status > XSTATUS_COUNT) - return 1; // Failure - - if (pData->flags & CSSF_UNICODE) { - char *text = (char*)nameXStatus[status - 1]; - MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, text, -1, pData->pwszName, MAX_PATH); - } - else mir_strcpy(pData->pszName, (char*)nameXStatus[status - 1]); - } - else { // moods does not support status title - if (!m_bXStatusEnabled) return 1; - - if (pData->flags & CSSF_UNICODE) { - char *str = getSettingStringUtf(hContact, DBSETTING_XSTATUS_NAME, ""); - WCHAR *wstr = make_unicode_string(str); - - mir_wstrcpy(pData->pwszName, wstr); - SAFE_FREE(&str); - SAFE_FREE(&wstr); - } - else { - DBVARIANT dbv; - if (!getString(hContact, DBSETTING_XSTATUS_NAME, &dbv) && dbv.pszVal) { - mir_strcpy(pData->pszName, dbv.pszVal); - db_free(&dbv); - } - else mir_strcpy(pData->pszName, ""); - } - } - } - - if (pData->flags & CSSF_MASK_MESSAGE) { // fill status message member - if (pData->flags & CSSF_UNICODE) { - char *str = getSettingStringUtf(hContact, CheckContactCapabilities(hContact, CAPF_STATUS_MOOD) ? DBSETTING_STATUS_NOTE : DBSETTING_XSTATUS_MSG, ""); - WCHAR *wstr = make_unicode_string(str); - - mir_wstrcpy(pData->pwszMessage, wstr); - SAFE_FREE(&str); - SAFE_FREE(&wstr); - } - else { - DBVARIANT dbv = { 0 }; - - if (!getString(hContact, CheckContactCapabilities(hContact, CAPF_STATUS_MOOD) ? DBSETTING_STATUS_NOTE : DBSETTING_XSTATUS_MSG, &dbv) && dbv.pszVal) - mir_strcpy(pData->pszMessage, dbv.pszVal); - else - mir_strcpy(pData->pszMessage, ""); - - db_free(&dbv); - } - } - - if (pData->flags & CSSF_DISABLE_UI) - if (pData->wParam) - *pData->wParam = !m_bHideXStatusUI; - - if (pData->flags & CSSF_DISABLE_MENU) - if (pData->wParam) - *pData->wParam = !m_bHideXStatusMenu; - - if (pData->flags & CSSF_STATUSES_COUNT) - if (pData->wParam) - *pData->wParam = XSTATUS_COUNT; - - if (pData->flags & CSSF_STR_SIZES) { - DBVARIANT dbv = { DBVT_DELETED }; - - if (pData->wParam) { - if (m_bXStatusEnabled && !getString(hContact, DBSETTING_XSTATUS_NAME, &dbv)) - *pData->wParam = mir_strlen(dbv.pszVal); - else - *pData->wParam = 0; - db_free(&dbv); - } - - if (pData->lParam) { - if (!getString(hContact, CheckContactCapabilities(hContact, CAPF_STATUS_MOOD) ? DBSETTING_STATUS_NOTE : DBSETTING_XSTATUS_MSG, &dbv)) - *pData->lParam = mir_strlen(dbv.pszVal); - else - *pData->lParam = 0; - db_free(&dbv); - } - } - - return 0; // Success -} - -INT_PTR CIcqProto::GetXStatusIcon(WPARAM wParam, LPARAM lParam) -{ - if (!m_bXStatusEnabled && !m_bMoodsEnabled) - return 0; - - if (!wParam) - wParam = getContactXStatus(NULL); - - if (wParam >= 1 && wParam <= XSTATUS_COUNT) - return (INT_PTR)getXStatusIcon((BYTE)wParam, lParam); - - return 0; -} - -INT_PTR CIcqProto::RequestXStatusDetails(WPARAM hContact, LPARAM) -{ - if (!m_bXStatusEnabled) - return 0; - - // user has xstatus, no auto-retrieve details, valid contact, request details - if (hContact && !getByte("XStatusAuto", DEFAULT_XSTATUS_AUTO) && getContactXStatus(hContact) && CheckContactCapabilities(hContact, CAPF_XSTATUS)) - return requestXStatusDetails(hContact, TRUE); - - return 0; -} - -INT_PTR CIcqProto::RequestAdvStatusIconIdx(WPARAM wParam, LPARAM) -{ - if (!m_bXStatusEnabled && !m_bMoodsEnabled) - return -1; - - BYTE bXStatus = getContactXStatus(wParam); - if (bXStatus) { - if (!bXStatusCListIconsValid[bXStatus - 1]) { // adding icon - int idx = hXStatusCListIcons[bXStatus - 1]; - HIMAGELIST hCListImageList = Clist_GetImageList(); - if (hCListImageList) { - HICON hXStatusIcon = getXStatusIcon(bXStatus, LR_SHARED); - - if (idx > 0) - ImageList_ReplaceIcon(hCListImageList, idx, hXStatusIcon); - else - hXStatusCListIcons[bXStatus - 1] = ImageList_AddIcon(hCListImageList, hXStatusIcon); - // mark icon index in the array as valid - bXStatusCListIconsValid[bXStatus - 1] = TRUE; - - IcoLib_ReleaseIcon(hXStatusIcon); - } - } - - int idx = bXStatusCListIconsValid[bXStatus - 1] ? hXStatusCListIcons[bXStatus - 1] : -1; - if (idx > 0) - return (idx & 0xFFFF) << 16; - } - return -1; -} diff --git a/protocols/IcqOscarJ/src/icq_xtraz.cpp b/protocols/IcqOscarJ/src/icq_xtraz.cpp deleted file mode 100644 index 5bf67c4095..0000000000 --- a/protocols/IcqOscarJ/src/icq_xtraz.cpp +++ /dev/null @@ -1,400 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// Internal Xtraz API -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -void CIcqProto::handleXtrazNotify(DWORD dwUin, DWORD dwMID, DWORD dwMID2, WORD wCookie, char* szMsg, size_t nMsgLen, BOOL bThruDC) -{ - char *szNotify = strstrnull(szMsg, ""); - char *szQuery = strstrnull(szMsg, ""); - - MCONTACT hContact = HContactFromUIN(dwUin, nullptr); - if (hContact) // user sent us xtraz, he supports it - SetContactCapabilities(hContact, CAPF_XTRAZ); - - if (szNotify && szQuery) { // valid request - char *szWork, *szEnd; - int nNotifyLen, nQueryLen; - - szNotify += 8; - szQuery += 7; - szEnd = strstrnull(szMsg, ""); - if (!szEnd) szEnd = szMsg + nMsgLen; - nNotifyLen = (szEnd - szNotify); - szEnd = strstrnull(szMsg, ""); - if (!szEnd) szEnd = szNotify; - szNotify = DemangleXml(szNotify, nNotifyLen); - nQueryLen = (szEnd - szQuery); - szQuery = DemangleXml(szQuery, nQueryLen); - szWork = strstrnull(szQuery, ""); - szEnd = strstrnull(szQuery, ""); - - debugLogA("Query: %s", szQuery); - debugLogA("Notify: %s", szNotify); - - if (szWork && szEnd) { // this is our plugin - szWork += 10; - *szEnd = '\0'; - - if (!mir_strcmpi(szWork, "srvMng") && strstrnull(szNotify, "AwayStat")) { - char *szSender = strstrnull(szNotify, ""); - char *szEndSend = strstrnull(szNotify, ""); - - if (szSender && szEndSend) { - szSender += 10; - *szEndSend = '\0'; - - if ((DWORD)atoi(szSender) == dwUin) { - BYTE dwXId = m_bXStatusEnabled ? getContactXStatus(NULL) : 0; - - if (dwXId && validateStatusMessageRequest(hContact, MTYPE_SCRIPT_NOTIFY)) { // apply privacy rules - NotifyEventHooks(m_modeMsgsEvent, (WPARAM)MTYPE_SCRIPT_NOTIFY, (LPARAM)dwUin); - - char *tmp = getSettingStringUtf(NULL, DBSETTING_XSTATUS_NAME, ""); - char *szXName = MangleXml(tmp, mir_strlen(tmp)); - SAFE_FREE(&tmp); - - tmp = getSettingStringUtf(NULL, DBSETTING_XSTATUS_MSG, ""); - char *szXMsg = MangleXml(tmp, mir_strlen(tmp)); - SAFE_FREE(&tmp); - - size_t nResponseLen = 212 + mir_strlen(szXName) + mir_strlen(szXMsg) + UINMAXLEN + 2; - char *szResponse = (char*)_alloca(nResponseLen + 1); - // send response - mir_snprintf(szResponse, nResponseLen, - "" - "cAwaySrv" - "" - "" - "%d" - "%d" - "%s" - "%s", - m_dwLocalUIN, dwXId, szXName, szXMsg); - - SAFE_FREE(&szXName); - SAFE_FREE(&szXMsg); - - struct rates_xstatus_response : public rates_queue_item - { - protected: - virtual rates_queue_item* copyItem(rates_queue_item *aDest = nullptr) - { - rates_xstatus_response *pDest = (rates_xstatus_response*)aDest; - if (!pDest) - pDest = new rates_xstatus_response(ppro, wGroup); - - pDest->bThruDC = bThruDC; - pDest->dwMsgID1 = dwMsgID1; - pDest->dwMsgID2 = dwMsgID2; - pDest->wCookie = wCookie; - pDest->szResponse = null_strdup(szResponse); - - return rates_queue_item::copyItem(pDest); - }; - public: - rates_xstatus_response(CIcqProto *ppro, WORD wGroup) : rates_queue_item(ppro, wGroup), szResponse(nullptr) {}; - virtual ~rates_xstatus_response() { if (bCreated) SAFE_FREE(&szResponse); }; - - virtual void execute() - { - ppro->SendXtrazNotifyResponse(dwUin, dwMsgID1, dwMsgID2, wCookie, szResponse, mir_strlen(szResponse), bThruDC); - }; - - BOOL bThruDC; - DWORD dwMsgID1; - DWORD dwMsgID2; - WORD wCookie; - char *szResponse; - }; - - WORD wGroup; - { - mir_cslock rlck(m_ratesMutex); - wGroup = m_rates->getGroupFromSNAC(ICQ_MSG_FAMILY, ICQ_MSG_RESPONSE); - } - - rates_xstatus_response rr(this, wGroup); - rr.hContact = hContact; - rr.dwUin = dwUin; - rr.bThruDC = bThruDC; - rr.dwMsgID1 = dwMID; - rr.dwMsgID2 = dwMID2; - rr.wCookie = wCookie; - rr.szResponse = szResponse; - - handleRateItem(&rr, RQT_RESPONSE, 0, !bThruDC); - } - else if (dwXId) - debugLogA("Privacy: Ignoring XStatus request"); - else - debugLogA("Error: We are not in XStatus, skipping"); - } - else debugLogA("Error: Invalid sender information"); - } - else debugLogA("Error: Missing sender information"); - } - else debugLogA("Error: Unknown plugin \"%s\" in Xtraz message", szWork); - } - else debugLogA("Error: Missing PluginID in Xtraz message"); - - SAFE_FREE(&szNotify); - SAFE_FREE(&szQuery); - } - else debugLogA("Error: Invalid Xtraz Notify message"); -} - -void CIcqProto::handleXtrazNotifyResponse(MCONTACT hContact, WORD wCookie, char* szMsg) -{ - char *szMem, *szRes, *szEnd; - size_t nResLen; - - debugLogA("Received Xtraz Notify Response"); - - szRes = strstrnull(szMsg, ""); - szEnd = strstrnull(szMsg, ""); - - if (szRes && szEnd) { // valid response - char *szNode, *szWork; - - szRes += 5; - nResLen = szEnd - szRes; - - szMem = szRes = DemangleXml(szRes, nResLen); - - debugLogA("Response: %s", szRes); - - ProtoBroadcastAck(hContact, ICQACKTYPE_XTRAZNOTIFY_RESPONSE, ACKRESULT_SUCCESS, (HANDLE)wCookie, (LPARAM)szRes); - -NextVal: - szNode = strstrnull(szRes, ""); else szEnd = nullptr; - - if (szNode && szEnd) { - *(szEnd - 1) = '\0'; - szNode += 13; //one more than the length of the string to skip ' or " too - szWork = szEnd + 1; - - if (!mir_strcmpi(szNode, "cAwaySrv")) { - int bChanged = FALSE; - - *szEnd = ' '; - szNode = strstrnull(szWork, ""); - szEnd = strstrnull(szWork, ""); - if (szNode && szEnd) { - szNode += 7; - *szEnd = '\0'; - if (atoi(szNode) != getContactXStatus(hContact)) { // this is strange - but go on - debugLogA("Warning: XStatusIds do not match!"); - } - *szEnd = ' '; - } - szNode = strstrnull(szWork, ""); - szEnd = strstrnull(szWork, ""); - if (szNode && szEnd) { // we got XStatus title, save it - char *szXName, *szOldXName; - szNode += 7; - *szEnd = '\0'; - szXName = DemangleXml(szNode, mir_strlen(szNode)); - // check if the name changed - szOldXName = getSettingStringUtf(hContact, DBSETTING_XSTATUS_NAME, nullptr); - if (mir_strcmp(szOldXName, szXName)) - bChanged = TRUE; - SAFE_FREE(&szOldXName); - db_set_utf(hContact, m_szModuleName, DBSETTING_XSTATUS_NAME, szXName); - SAFE_FREE(&szXName); - *szEnd = ' '; - } - szNode = strstrnull(szWork, ""); - szEnd = strstrnull(szWork, ""); - if (szNode && szEnd) { // we got XStatus mode msg, save it - char *szXMsg, *szOldXMsg; - szNode += 6; - *szEnd = '\0'; - szXMsg = DemangleXml(szNode, mir_strlen(szNode)); - // check if the decription changed - szOldXMsg = getSettingStringUtf(hContact, DBSETTING_XSTATUS_NAME, nullptr); - if (mir_strcmp(szOldXMsg, szXMsg)) - bChanged = TRUE; - SAFE_FREE(&szOldXMsg); - db_set_utf(hContact, m_szModuleName, DBSETTING_XSTATUS_MSG, szXMsg); - SAFE_FREE(&szXMsg); - } - ProtoBroadcastAck(hContact, ICQACKTYPE_XSTATUS_RESPONSE, ACKRESULT_SUCCESS, (HANDLE)wCookie, 0); - } - else { - char *szSrvEnd = strstrnull(szEnd, ""); - - if (szSrvEnd && strstrnull(szSrvEnd, ""); - const char *szEnd = strstrnull(szData, ""); - - if (szPid && szEnd) { - szPid += 5; - return DemangleXml(szPid, szEnd - szPid); - } - return nullptr; -} - -void CIcqProto::handleXtrazInvitation(DWORD dwUin, char* szMsg, BOOL bThruDC) -{ - MCONTACT hContact = HContactFromUIN(dwUin, nullptr); - if (hContact) // user sent us xtraz, he supports it - SetContactCapabilities(hContact, CAPF_XTRAZ); - - char *szPluginID = getXmlPidItem(szMsg); - if (!mir_strcmp(szPluginID, "ICQChatRecv")) // it is a invitation to multi-user chat - ; - else - NetLog_Uni(bThruDC, "Error: Unknown plugin \"%s\" in Xtraz message", szPluginID); - - SAFE_FREE(&szPluginID); -} - -void CIcqProto::handleXtrazData(DWORD dwUin, char* szMsg, BOOL bThruDC) -{ - MCONTACT hContact = HContactFromUIN(dwUin, nullptr); - if (hContact) // user sent us xtraz, he supports it - SetContactCapabilities(hContact, CAPF_XTRAZ); - - char *szPluginID = getXmlPidItem(szMsg); - if (!mir_strcmp(szPluginID, "viewCard")) { // it is a greeting card - char *szWork, *szEnd, *szUrl, *szNum; - - szWork = strstrnull(szMsg, ""); - szEnd = strstrnull(szMsg, ""); - if (szWork && szEnd) { - int nDataLen = szEnd - szWork; - - szUrl = (char*)_alloca(nDataLen); - memcpy(szUrl, szWork + 5, nDataLen); - szUrl[nDataLen - 5] = '\0'; - - if (!_strnicmp(szUrl, "view_", 5)) { - szNum = szUrl + 5; - szWork = strstrnull(szUrl, ".html"); - if (szWork) { - mir_strcpy(szWork, ".php"); - mir_strcat(szWork, szWork + 5); - } - while (szWork = strstrnull(szUrl, "&")) // unescape & code - mir_strcpy(szWork + 1, szWork + 5); - - szWork = (char*)SAFE_MALLOC(nDataLen + MAX_PATH); - ICQTranslateUtfStatic(LPGEN("Greeting card:"), szWork, MAX_PATH); - mir_strcat(szWork, "\r\nhttp://www.icq.com/friendship/pages/view_page_"); - mir_strcat(szWork, szNum); - - // Create message to notify user - PROTORECVEVENT pre = { 0 }; - pre.timestamp = time(0); - pre.szMessage = szWork; - - int bAdded; - ProtoChainRecvMsg(HContactFromUIN(dwUin, &bAdded), &pre); - - SAFE_FREE(&szWork); - } - else NetLog_Uni(bThruDC, "Error: Non-standard greeting card message"); - } - else NetLog_Uni(bThruDC, "Error: Malformed greeting card message"); - } - else NetLog_Uni(bThruDC, "Error: Unknown plugin \"%s\" in Xtraz message", szPluginID); - - SAFE_FREE(&szPluginID); -} - -// Functions really sending Xtraz stuff -DWORD CIcqProto::SendXtrazNotifyRequest(MCONTACT hContact, char* szQuery, char* szNotify, int bForced) -{ - DWORD dwUin; - if (getContactUid(hContact, &dwUin, nullptr)) - return 0; // Invalid contact - - if (!CheckContactCapabilities(hContact, CAPF_XTRAZ) && !bForced) - return 0; // Contact does not support xtraz, do not send anything - - char *szQueryBody = MangleXml(szQuery, mir_strlen(szQuery)); - char *szNotifyBody = MangleXml(szNotify, mir_strlen(szNotify)); - size_t nBodyLen = mir_strlen(szQueryBody) + mir_strlen(szNotifyBody) + 41; - char *szBody = (char*)_alloca(nBodyLen); - nBodyLen = mir_snprintf(szBody, nBodyLen, "%s%s", szQueryBody, szNotifyBody); - SAFE_FREE((void**)&szQueryBody); - SAFE_FREE((void**)&szNotifyBody); - - // Set up the ack type - cookie_message_data *pCookieData = CreateMessageCookie(MTYPE_SCRIPT_NOTIFY, ACKTYPE_CLIENT); - DWORD dwCookie = AllocateCookie(CKT_MESSAGE, 0, hContact, (void*)pCookieData); - - // have we a open DC, send through that - if (m_bDCMsgEnabled && IsDirectConnectionOpen(hContact, DIRECTCONN_STANDARD, 0)) - icq_sendXtrazRequestDirect(hContact, dwCookie, szBody, nBodyLen, MTYPE_SCRIPT_NOTIFY); - else - icq_sendXtrazRequestServ(dwUin, dwCookie, szBody, nBodyLen, pCookieData); - - return dwCookie; -} - -void CIcqProto::SendXtrazNotifyResponse(DWORD dwUin, DWORD dwMID, DWORD dwMID2, WORD wCookie, char* szResponse, size_t nResponseLen, BOOL bThruDC) -{ - char *szResBody = MangleXml(szResponse, nResponseLen); - size_t nBodyLen = mir_strlen(szResBody) + 21; - char *szBody = (char*)_alloca(nBodyLen); - MCONTACT hContact = HContactFromUIN(dwUin, nullptr); - - if (hContact != INVALID_CONTACT_ID && !CheckContactCapabilities(hContact, CAPF_XTRAZ)) { - SAFE_FREE(&szResBody); - return; // Contact does not support xtraz, do not send anything - } - - nBodyLen = mir_snprintf(szBody, nBodyLen, "%s", szResBody); - SAFE_FREE(&szResBody); - - // Was request received thru DC and have we a open DC, send through that - if (bThruDC && IsDirectConnectionOpen(hContact, DIRECTCONN_STANDARD, 0)) - icq_sendXtrazResponseDirect(hContact, wCookie, szBody, nBodyLen, MTYPE_SCRIPT_NOTIFY); - else - icq_sendXtrazResponseServ(dwUin, dwMID, dwMID2, wCookie, szBody, nBodyLen, MTYPE_SCRIPT_NOTIFY); -} diff --git a/protocols/IcqOscarJ/src/icqosc_svcs.cpp b/protocols/IcqOscarJ/src/icqosc_svcs.cpp deleted file mode 100644 index d84a66fcf4..0000000000 --- a/protocols/IcqOscarJ/src/icqosc_svcs.cpp +++ /dev/null @@ -1,679 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// High-level code for exported API services -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -INT_PTR CIcqProto::AddServerContact(WPARAM hContact, LPARAM) -{ - if (!m_bSsiEnabled) return 0; - - // Does this contact have a UID? - DWORD dwUin; - uid_str szUid; - if (!getContactUid(hContact, &dwUin, &szUid) && !getWord(hContact, DBSETTING_SERVLIST_ID, 0) && !getWord(hContact, DBSETTING_SERVLIST_IGNORE, 0)) { - /// TODO: remove possible 0x6A TLV in contact server-list data!!! - // Read group from DB - char *pszGroup = getContactCListGroup(hContact); - - servlistAddContact(hContact, pszGroup); - SAFE_FREE((void**)&pszGroup); - } - return 0; -} - -static int LookupDatabaseSetting(const FieldNamesItem* table, int code, DBVARIANT *dbv, BYTE type) -{ - char *text = LookupFieldName(table, code); - if (!text) { - dbv->type = DBVT_DELETED; - return 1; - } - - if (type == DBVT_ASCIIZ) { - dbv->pszVal = mir_strdup(Translate(text)); - dbv->type = DBVT_ASCIIZ; - } - else if (type == DBVT_UTF8 || !type) { - char tmp[MAX_PATH]; - dbv->pszVal = mir_strdup(ICQTranslateUtfStatic(text, tmp, MAX_PATH)); - dbv->type = DBVT_UTF8; - } - else if (type == DBVT_WCHAR) { - WCHAR* wtext = make_unicode_string(text); - dbv->pwszVal = mir_wstrdup(TranslateW(wtext)); - dbv->type = DBVT_WCHAR; - SAFE_FREE((void**)&wtext); - } - return 0; // Success -} - -INT_PTR CIcqProto::GetInfoSetting(WPARAM hContact, LPARAM lParam) -{ - DBCONTACTGETSETTING *cgs = (DBCONTACTGETSETTING*)lParam; - BYTE type = cgs->pValue->type; - INT_PTR rc = db_get_s(hContact, cgs->szModule, cgs->szSetting, cgs->pValue, 0); - if (rc) - return rc; - - // Success - DBVARIANT dbv = *cgs->pValue; - if (dbv.type == DBVT_BLOB) { - cgs->pValue->pbVal = (BYTE*)mir_alloc(dbv.cpbVal); - memcpy(cgs->pValue->pbVal, dbv.pbVal, dbv.cpbVal); - } - else if (dbv.type == DBVT_ASCIIZ || dbv.type == DBVT_UTF8) { - // convert to the desired type - if (!type) - type = dbv.type; - - // type is correct, only move it to miranda's heap - if (dbv.type == type) - cgs->pValue->pszVal = mir_strdup(dbv.pszVal); - else if (type == DBVT_WCHAR) { - if (dbv.type != DBVT_UTF8) { - int len = MultiByteToWideChar(CP_ACP, 0, dbv.pszVal, -1, nullptr, 0); - cgs->pValue->pwszVal = (WCHAR*)mir_alloc((len + 1) * sizeof(WCHAR)); - if (cgs->pValue->pwszVal == nullptr) - rc = 1; - else { - MultiByteToWideChar(CP_ACP, 0, dbv.pszVal, -1, cgs->pValue->pwszVal, len); - cgs->pValue->pwszVal[len] = '\0'; - } - } - else { - char *savePtr = dbv.pszVal ? mir_strcpy((char*)_alloca(mir_strlen(dbv.pszVal) + 1), dbv.pszVal) : nullptr; - if (!mir_utf8decode(savePtr, &cgs->pValue->pwszVal)) - rc = 1; - } - } - else if (type == DBVT_UTF8) { - cgs->pValue->pszVal = mir_utf8encode(dbv.pszVal); - if (cgs->pValue->pszVal == nullptr) - rc = 1; - } - else if (type == DBVT_ASCIIZ) { - cgs->pValue->pszVal = mir_strdup(dbv.pszVal); - mir_utf8decode(cgs->pValue->pszVal, nullptr); - } - - cgs->pValue->type = type; - } - else if (!mir_strcmp(cgs->szModule, m_szModuleName) && (dbv.type == DBVT_BYTE || dbv.type == DBVT_WORD || dbv.type == DBVT_DWORD)) { - int code = (dbv.type == DBVT_BYTE) ? dbv.bVal : ((dbv.type == DBVT_WORD) ? dbv.wVal : dbv.dVal); - - if (!mir_strcmp(cgs->szSetting, "Language1") || !mir_strcmp(cgs->szSetting, "Language2") || !mir_strcmp(cgs->szSetting, "Language3")) - rc = LookupDatabaseSetting(languageField, code, cgs->pValue, type); - else if (!mir_strcmp(cgs->szSetting, "Country") || !mir_strcmp(cgs->szSetting, "OriginCountry") || !mir_strcmp(cgs->szSetting, "CompanyCountry")) { - if (code == 420) code = 42; // conversion of obsolete codes (OMG!) - else if (code == 421) code = 4201; - else if (code == 102) code = 1201; - rc = LookupDatabaseSetting(countryField, code, cgs->pValue, type); - } - else if (!mir_strcmp(cgs->szSetting, "Gender")) - rc = LookupDatabaseSetting(genderField, code, cgs->pValue, type); - else if (!mir_strcmp(cgs->szSetting, "MaritalStatus")) - rc = LookupDatabaseSetting(maritalField, code, cgs->pValue, type); - else if (!mir_strcmp(cgs->szSetting, "StudyLevel")) - rc = LookupDatabaseSetting(studyLevelField, code, cgs->pValue, type); - else if (!mir_strcmp(cgs->szSetting, "CompanyIndustry")) - rc = LookupDatabaseSetting(industryField, code, cgs->pValue, type); - else if (!mir_strcmp(cgs->szSetting, "Interest0Cat") || !mir_strcmp(cgs->szSetting, "Interest1Cat") || !mir_strcmp(cgs->szSetting, "Interest2Cat") || !mir_strcmp(cgs->szSetting, "Interest3Cat")) - rc = LookupDatabaseSetting(interestsField, code, cgs->pValue, type); - } - // Release database memory - db_free(&dbv); - return rc; -} - -INT_PTR CIcqProto::ChangeInfoEx(WPARAM wParam, LPARAM) -{ - if (!icqOnline() || !wParam) - return 0; - - PBYTE buf = nullptr; - size_t buflen = 0; - - // userinfo - ppackTLVWord(&buf, &buflen, 0x1C2, (WORD)GetACP()); - - if (wParam & CIXT_CONTACT) { // contact information - BYTE *pBlock = nullptr; - size_t cbBlock = 0; - int nItems = 0; - - // Emails - nItems += ppackTLVWordStringItemFromDB(&pBlock, &cbBlock, "e-mail0", 0x78, 0x64, 0x00); - nItems += ppackTLVWordStringItemFromDB(&pBlock, &cbBlock, "e-mail1", 0x78, 0x64, 0x00); - nItems += ppackTLVWordStringItemFromDB(&pBlock, &cbBlock, "e-mail2", 0x78, 0x64, 0x00); - ppackTLVBlockItems(&buf, &buflen, 0x8C, &nItems, &pBlock, (WORD*)&cbBlock, FALSE); - - // Phones - nItems += ppackTLVWordStringItemFromDB(&pBlock, &cbBlock, "Phone", 0x6E, 0x64, 0x01); - nItems += ppackTLVWordStringItemFromDB(&pBlock, &cbBlock, "CompanyPhone", 0x6E, 0x64, 0x02); - nItems += ppackTLVWordStringItemFromDB(&pBlock, &cbBlock, "Cellular", 0x6E, 0x64, 0x03); - nItems += ppackTLVWordStringItemFromDB(&pBlock, &cbBlock, "Fax", 0x6E, 0x64, 0x04); - nItems += ppackTLVWordStringItemFromDB(&pBlock, &cbBlock, "CompanyFax", 0x6E, 0x64, 0x05); - ppackTLVBlockItems(&buf, &buflen, 0xC8, &nItems, &pBlock, (WORD*)&cbBlock, FALSE); - - ppackTLVByte(&buf, &buflen, 0x1EA, getByte("AllowSpam", 0)); - } - - if (wParam & CIXT_BASIC) { // upload basic user info - ppackTLVStringUtfFromDB(&buf, &buflen, "Nick", 0x78); - ppackTLVStringUtfFromDB(&buf, &buflen, "FirstName", 0x64); - ppackTLVStringUtfFromDB(&buf, &buflen, "LastName", 0x6E); - ppackTLVStringUtfFromDB(&buf, &buflen, "About", 0x186); - } - - if (wParam & CIXT_MORE) { - BYTE b = getByte("Gender", 0); - ppackTLVByte(&buf, &buflen, 0x82, (BYTE)(b ? (b == 'M' ? 2 : 1) : 0)); - - ppackTLVDateFromDB(&buf, &buflen, "BirthYear", "BirthMonth", "BirthDay", 0x1A4); - - ppackTLVWord(&buf, &buflen, 0xAA, getByte("Language1", 0)); - ppackTLVWord(&buf, &buflen, 0xB4, getByte("Language2", 0)); - ppackTLVWord(&buf, &buflen, 0xBE, getByte("Language3", 0)); - - ppackTLVWord(&buf, &buflen, 0x12C, getByte("MaritalStatus", 0)); - } - - if (wParam & CIXT_WORK) { - BYTE *pBlock = nullptr; - size_t cbBlock = 0; - int nItems = 1; - - // Jobs - ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "CompanyPosition", 0x64); - ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "Company", 0x6E); - ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "CompanyDepartment", 0x7D); - ppackTLVStringFromDB(&pBlock, &cbBlock, "CompanyHomepage", 0x78); - ppackTLVWord(&pBlock, &cbBlock, 0x82, getWord("CompanyIndustry", 0)); - ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "CompanyStreet", 0xAA); - ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "CompanyCity", 0xB4); - ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "CompanyState", 0xBE); - ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "CompanyZIP", 0xC8); - ppackTLVDWord(&pBlock, &cbBlock, 0xD2, getWord("CompanyCountry", 0)); - /// TODO: pack unknown data (need to preserve them in Block Items) - ppackTLVBlockItems(&buf, &buflen, 0x118, &nItems, &pBlock, (WORD*)&cbBlock, TRUE); - - // ppackTLVWord(&buf, &buflen, getWord("CompanyOccupation", 0), TLV_OCUPATION, 1); // Lost In Conversion - } - - if (wParam & CIXT_EDUCATION) { - BYTE *pBlock = nullptr; - size_t cbBlock = 0; - int nItems = 1; - - // Studies - ppackTLVWord(&pBlock, &cbBlock, 0x64, getWord("StudyLevel", 0)); - ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "StudyInstitute", 0x6E); - ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "StudyDegree", 0x78); - ppackTLVWord(&pBlock, &cbBlock, 0x8C, getWord("StudyYear", 0)); - ppackTLVBlockItems(&buf, &buflen, 0x10E, &nItems, &pBlock, (WORD*)&cbBlock, TRUE); - } - - if (wParam & CIXT_LOCATION) { - BYTE *pBlock = nullptr; - size_t cbBlock = 0; - int nItems = 1; - - // Home Address - ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "Street", 0x64); - ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "City", 0x6E); - ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "State", 0x78); - ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "ZIP", 0x82); - ppackTLVDWord(&pBlock, &cbBlock, 0x8C, getWord("Country", 0)); - ppackTLVBlockItems(&buf, &buflen, 0x96, &nItems, &pBlock, (WORD*)&cbBlock, TRUE); - - nItems = 1; - // Origin Address - ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "OriginStreet", 0x64); - ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "OriginCity", 0x6E); - ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "OriginState", 0x78); - ppackTLVDWord(&pBlock, &cbBlock, 0x8C, getWord("OriginCountry", 0)); - ppackTLVBlockItems(&buf, &buflen, 0xA0, &nItems, &pBlock, (WORD*)&cbBlock, TRUE); - - ppackTLVStringFromDB(&buf, &buflen, "Homepage", 0xFA); - - // Timezone - WORD wTimezone = getByte("Timezone", 0); - if ((wTimezone & 0x0080) == 0x80) wTimezone |= 0xFF00; // extend signed number - ppackTLVWord(&buf, &buflen, 0x17C, wTimezone); - } - - if (wParam & CIXT_BACKGROUND) { - BYTE *pBlock = nullptr; - size_t cbBlock = 0; - int nItems = 0; - - // Interests - nItems += ppackTLVWordStringUtfItemFromDB(&pBlock, &cbBlock, "Interest0Text", 0x6E, 0x64, getWord("Interest0Cat", 0)); - nItems += ppackTLVWordStringUtfItemFromDB(&pBlock, &cbBlock, "Interest1Text", 0x6E, 0x64, getWord("Interest1Cat", 0)); - nItems += ppackTLVWordStringUtfItemFromDB(&pBlock, &cbBlock, "Interest2Text", 0x6E, 0x64, getWord("Interest2Cat", 0)); - nItems += ppackTLVWordStringUtfItemFromDB(&pBlock, &cbBlock, "Interest3Text", 0x6E, 0x64, getWord("Interest3Cat", 0)); - ppackTLVBlockItems(&buf, &buflen, 0x122, &nItems, &pBlock, (WORD*)&cbBlock, FALSE); - } - - DWORD dwCookie = icq_changeUserDirectoryInfoServ(buf, buflen, DIRECTORYREQUEST_UPDATEOWNER); - - SAFE_FREE((void**)&buf); - - return dwCookie; -} - -INT_PTR CIcqProto::GetAvatarCaps(WPARAM wParam, LPARAM lParam) -{ - if (wParam == AF_MAXSIZE) { - POINT *size = (POINT*)lParam; - if (size) { - size->x = 64; - size->y = 64; - } - return 0; - } - - if (wParam == AF_PROPORTION) - return PIP_NONE; - - if (wParam == AF_FORMATSUPPORTED) - return (lParam == PA_FORMAT_JPEG || lParam == PA_FORMAT_GIF || lParam == PA_FORMAT_XML || lParam == PA_FORMAT_BMP); - - if (wParam == AF_ENABLED) - return (m_bSsiEnabled && m_bAvatarsEnabled); - - if (wParam == AF_DONTNEEDDELAYS) - return 0; - - // server accepts images of 7168 bytees, not bigger - if (wParam == AF_MAXFILESIZE) - return 7168; - - // do not request avatar again if server gave an error - if (wParam == AF_DELAYAFTERFAIL) - return 1 * 60 * 60 * 1000; // one hour - - // avatars can be fetched all the time (server only operation) - if (wParam == AF_FETCHIFPROTONOTVISIBLE || wParam == AF_FETCHIFCONTACTOFFLINE) - return 1; - - return 0; -} - -INT_PTR CIcqProto::GetAvatarInfo(WPARAM wParam, LPARAM lParam) -{ - PROTO_AVATAR_INFORMATION *pai = (PROTO_AVATAR_INFORMATION*)lParam; - DWORD dwUIN; - uid_str szUID; - DBVARIANT dbv = { DBVT_DELETED }; - - if (!m_bAvatarsEnabled) return GAIR_NOAVATAR; - - if (getSetting(pai->hContact, "AvatarHash", &dbv) || dbv.type != DBVT_BLOB || (dbv.cpbVal != 0x14 && dbv.cpbVal != 0x09)) { - db_free(&dbv); - return GAIR_NOAVATAR; // we did not found avatar hash or hash invalid - no avatar available - } - - if (getContactUid(pai->hContact, &dwUIN, &szUID)) { - db_free(&dbv); - return GAIR_NOAVATAR; // we do not support avatars for invalid contacts - } - - int dwPaFormat = getByte(pai->hContact, "AvatarType", PA_FORMAT_UNKNOWN); - - if (dwPaFormat != PA_FORMAT_UNKNOWN) { // we know the format, test file - wchar_t tszFile[MAX_PATH * 2 + 4]; - - GetFullAvatarFileName(dwUIN, szUID, dwPaFormat, tszFile, MAX_PATH * 2); - - mir_wstrncpy(pai->filename, tszFile, _countof(pai->filename)); // Avatar API does not support unicode :-( - pai->format = dwPaFormat; - - if (!IsAvatarChanged(pai->hContact, dbv.pbVal, dbv.cpbVal)) { // hashes are the same - if (_waccess(tszFile, 0) == 0) { - db_free(&dbv); - - return GAIR_SUCCESS; // we have found the avatar file, whoala - } - } - } - - if (IsAvatarChanged(pai->hContact, dbv.pbVal, dbv.cpbVal)) { // we didn't received the avatar before - this ensures we will not request avatar again and again - if ((wParam & GAIF_FORCE) != 0 && pai->hContact != 0) { // request avatar data - wchar_t tszFile[MAX_PATH * 2 + 4]; - - GetAvatarFileName(dwUIN, szUID, tszFile, MAX_PATH * 2); - GetAvatarData(pai->hContact, dwUIN, szUID, dbv.pbVal, dbv.cpbVal, tszFile); - mir_wstrncpy(pai->filename, tszFile, _countof(pai->filename)); // Avatar API does not support unicode :-( - - db_free(&dbv); - - return GAIR_WAITFOR; - } - } - db_free(&dbv); - - return GAIR_NOAVATAR; -} - - -INT_PTR CIcqProto::GetMyAvatar(WPARAM wParam, LPARAM lParam) -{ - if (!m_bAvatarsEnabled) return -2; - - if (!wParam) return -3; - - wchar_t *tszFile = GetOwnAvatarFileName(); - if (tszFile && !_waccess(tszFile, 0)) { - wcsncpy((wchar_t*)wParam, tszFile, (int)lParam); - SAFE_FREE(&tszFile); - return 0; - } - - SAFE_FREE(&tszFile); - return -1; -} - - -INT_PTR CIcqProto::GrantAuthorization(WPARAM wParam, LPARAM) -{ - if (icqOnline() && wParam != 0) { - DWORD dwUin; - uid_str szUid; - if (getContactUid(wParam, &dwUin, &szUid)) - return 0; // Invalid contact - - // send without reason, do we need any ? - icq_sendGrantAuthServ(dwUin, szUid, nullptr); - // auth granted, remove contact menu item - delSetting(wParam, "Grant"); - } - - return 0; -} - -int CIcqProto::OnIdleChanged(WPARAM, LPARAM lParam) -{ - int bIdle = (lParam & IDF_ISIDLE); - int bPrivacy = (lParam & IDF_PRIVACY); - if (bPrivacy) { - debugLogA("ICQ: idle mode ignored due to the private mode: %08x", lParam); - return 0; - } - - setDword("IdleTS", bIdle ? time(0) : 0); - - if (m_bTempVisListEnabled) // remove temporary visible users - sendEntireListServ(ICQ_BOS_FAMILY, ICQ_CLI_REMOVETEMPVISIBLE, BUL_TEMPVISIBLE); - - icq_setidle(bIdle != 0); - return 0; -} - -INT_PTR CIcqProto::RevokeAuthorization(WPARAM wParam, LPARAM) -{ - if (icqOnline() && wParam != 0) { - DWORD dwUin; - uid_str szUid; - if (getContactUid(wParam, &dwUin, &szUid)) - return 0; // Invalid contact - - if (MessageBox(nullptr, TranslateT("Are you sure you want to revoke user's authorization?\nThis will remove you from his/her list on some clients."), TranslateT("Confirmation"), MB_ICONQUESTION | MB_YESNO) != IDYES) - return 0; - - icq_sendRevokeAuthServ(dwUin, szUid); - } - - return 0; -} - - -INT_PTR CIcqProto::SendSms(WPARAM wParam, LPARAM lParam) -{ - if (icqOnline() && wParam && lParam) - return icq_sendSMSServ((const char *)wParam, (const char *)lParam); - - return 0; // Failure -} - -INT_PTR CIcqProto::SendYouWereAdded(WPARAM, LPARAM lParam) -{ - if (lParam && icqOnline()) { - CCSDATA* ccs = (CCSDATA*)lParam; - if (ccs->hContact) { - DWORD dwUin; - if (getContactUid(ccs->hContact, &dwUin, nullptr)) - return 1; // Invalid contact - - DWORD dwMyUin = getContactUin(NULL); - if (dwUin) { - icq_sendYouWereAddedServ(dwUin, dwMyUin); - return 0; // Success - } - } - } - - return 1; // Failure -} - -INT_PTR CIcqProto::SetMyAvatar(WPARAM, LPARAM lParam) -{ - if (!m_bAvatarsEnabled || !m_bSsiEnabled) - return -2; - - wchar_t *tszFile = (wchar_t*)lParam; - if (tszFile) { // set file for avatar - int dwPaFormat = ::ProtoGetAvatarFileFormat(tszFile); - if (dwPaFormat != PA_FORMAT_XML) { - // if it should be image, check if it is valid - HBITMAP avt = Bitmap_Load(tszFile); - if (!avt) - return -1; - - DeleteObject(avt); - } - - wchar_t tszMyFile[MAX_PATH + 1]; - GetFullAvatarFileName(0, nullptr, dwPaFormat, tszMyFile, MAX_PATH); - - // if not in our storage, copy - if (mir_wstrcmp(tszFile, tszMyFile) && !CopyFile(tszFile, tszMyFile, FALSE)) { - debugLogA("Failed to copy our avatar to local storage."); - return -1; - } - - BYTE *hash = calcMD5HashOfFile(tszMyFile); - if (hash == nullptr) - return -1; - - BYTE ihash[0x14]; - // upload hash to server - ihash[0] = 0; //unknown - ihash[1] = dwPaFormat == PA_FORMAT_XML ? AVATAR_HASH_FLASH : AVATAR_HASH_STATIC; //hash type - ihash[2] = 1; //hash status - ihash[3] = 0x10; //hash len - memcpy((ihash + 4), hash, 0x10); - updateServAvatarHash(ihash, 0x14); - - if (setSettingBlob(NULL, "AvatarHash", ihash, 0x14)) - debugLogA("Failed to save avatar hash."); - - wchar_t tmp[MAX_PATH]; - PathToRelativeW(tszMyFile, tmp); - setWString(NULL, "AvatarFile", tmp); - SAFE_FREE((void**)&hash); - } - else { - // delete user avatar - delSetting("AvatarFile"); - setSettingBlob(NULL, "AvatarHash", hashEmptyAvatar, 9); - updateServAvatarHash(hashEmptyAvatar, 9); // set blank avatar - } - return 0; -} - -INT_PTR CIcqProto::SetNickName(WPARAM wParam, LPARAM lParam) -{ - if (!icqOnline()) - return 0; // failure - - if (wParam & SMNN_UNICODE) - setWString("Nick", (WCHAR*)lParam); - else - setString("Nick", (char*)lParam); - - return ChangeInfoEx(CIXT_BASIC, 0); -} - -// TODO: Adding needs some more work in general - -MCONTACT CIcqProto::AddToListByUIN(DWORD dwUin, DWORD dwFlags) -{ - int bAdded; - MCONTACT hContact = HContactFromUIN(dwUin, &bAdded); - if (hContact == NULL) // Failure - return NULL; - - if (!(dwFlags & PALF_TEMPORARY) && db_get_b(hContact, "CList", "NotOnList", 0)) { - setContactHidden(hContact, 0); - db_unset(hContact, "CList", "NotOnList"); - } - return hContact; // Success -} - -MCONTACT CIcqProto::AddToListByUID(const char *szUID, DWORD dwFlags) -{ - int bAdded; - MCONTACT hContact = HContactFromUID(0, szUID, &bAdded); - if (hContact == 0) - return 0; // Failure - - if (!(dwFlags & PALF_TEMPORARY) && db_get_b(hContact, "CList", "NotOnList", 0)) { - setContactHidden(hContact, 0); - db_unset(hContact, "CList", "NotOnList"); - } - - return hContact; // Success -} - - -///////////////////////////////////////////////////////////////////////////////////////// - -void CIcqProto::ICQAddRecvEvent(MCONTACT hContact, WORD wType, PROTORECVEVENT* pre, size_t cbBlob, PBYTE pBlob, DWORD flags) -{ - flags |= DBEF_UTF; - if (pre->flags & PREF_CREATEREAD) - flags |= DBEF_READ; - - if (hContact && db_get_b(hContact, "CList", "Hidden", 0)) { - // if the contact was hidden, add to client-list if not in server-list authed - if (!getWord(hContact, DBSETTING_SERVLIST_ID, 0) || getByte(hContact, "Auth", 0)) { - DWORD dwUin; - uid_str szUid; - getContactUid(hContact, &dwUin, &szUid); - icq_sendNewContact(dwUin, szUid); /// FIXME - } - } - - AddEvent(hContact, wType, pre->timestamp, flags, cbBlob, pBlob); -} - -INT_PTR __cdecl CIcqProto::IcqAddCapability(WPARAM, LPARAM lParam) -{ - ICQ_CUSTOMCAP *icqCustomCapIn = (ICQ_CUSTOMCAP*)lParam; - ICQ_CUSTOMCAP *icqCustomCap = new ICQ_CUSTOMCAP; - memcpy(icqCustomCap, icqCustomCapIn, sizeof(ICQ_CUSTOMCAP)); - CustomCapList.insert(icqCustomCap); - return 0; -} - - -INT_PTR __cdecl CIcqProto::IcqCheckCapability(WPARAM hContact, LPARAM lParam) -{ - int res = 0; - DBVARIANT dbvariant; - ICQ_CUSTOMCAP *icqCustomCap = (ICQ_CUSTOMCAP *)lParam; - - db_get(hContact, m_szModuleName, "CapBuf", &dbvariant); - if (dbvariant.type == DBVT_BLOB) - res = MatchCapability(dbvariant.pbVal, dbvariant.cpbVal, (const capstr*)&icqCustomCap->caps, 0x10) ? 1 : 0; // FIXME: Why icqCustomCap->caps is not capstr? - - db_free(&dbvariant); - return res; -} - - - -///////////////////////////////////////////////////////////////////////////////////////// - -INT_PTR icq_getEventTextMissedMessage(WPARAM pEvent, LPARAM datatype) -{ - DBEVENTINFO *dbei = (DBEVENTINFO *)pEvent; - - INT_PTR nRetVal = 0; - char *pszText = nullptr; - - if (dbei->cbBlob > 1) { - switch (((WORD*)dbei->pBlob)[0]) { - case 0: - pszText = LPGEN("** This message was blocked by the ICQ server ** The message was invalid."); - break; - - case 1: - pszText = LPGEN("** This message was blocked by the ICQ server ** The message was too long."); - break; - - case 2: - pszText = LPGEN("** This message was blocked by the ICQ server ** The sender has flooded the server."); - break; - - case 4: - pszText = LPGEN("** This message was blocked by the ICQ server ** You are too evil."); - break; - - default: - pszText = LPGEN("** Unknown missed message event."); - break; - } - if (datatype == DBVT_WCHAR) { - int wchars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pszText, (int)mir_strlen(pszText), nullptr, 0); - - WCHAR *pwszText = (WCHAR*)_alloca((wchars + 1) * sizeof(WCHAR)); - pwszText[wchars] = 0; - - MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pszText, (int)mir_strlen(pszText), pwszText, wchars); - - nRetVal = (INT_PTR)mir_wstrdup(TranslateW(pwszText)); - } - else if (datatype == DBVT_ASCIIZ) - nRetVal = (INT_PTR)mir_strdup(Translate(pszText)); - } - - return nRetVal; -} diff --git a/protocols/IcqOscarJ/src/icqosc_svcs.h b/protocols/IcqOscarJ/src/icqosc_svcs.h deleted file mode 100644 index 96ed6ca2ae..0000000000 --- a/protocols/IcqOscarJ/src/icqosc_svcs.h +++ /dev/null @@ -1,35 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2008 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// ----------------------------------------------------------------------------- - -#ifndef __ICQOSC_SVCS_H -#define __ICQOSC_SVCS_H - - -#define ICQ_DB_GETEVENTTEXT_MISSEDMESSAGE "ICQ/GetEventTextMissedMessage" - -INT_PTR icq_getEventTextMissedMessage(WPARAM wParam, LPARAM lParam); - - -#endif /* __ICQOSC_SVCS_H */ diff --git a/protocols/IcqOscarJ/src/init.cpp b/protocols/IcqOscarJ/src/init.cpp deleted file mode 100644 index 5576337788..0000000000 --- a/protocols/IcqOscarJ/src/init.cpp +++ /dev/null @@ -1,149 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -#include "m_extraicons.h" -#include "m_icolib.h" - -BOOL bPopupService = FALSE; - -HANDLE hExtraXStatus; - -///////////////////////////////////////////////////////////////////////////////////////// - -static PLUGININFOEX pluginInfoEx = { - sizeof(PLUGININFOEX), - __PLUGIN_NAME, - PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM), - __DESCRIPTION, - __AUTHOR, - __COPYRIGHT, - __AUTHORWEB, - UNICODE_AWARE, //doesn't replace anything built-in - { 0x73a9615c, 0x7d4e, 0x4555, { 0xba, 0xdb, 0xee, 0x5, 0xdc, 0x92, 0x8e, 0xff } } // {73A9615C-7D4E-4555-BADB-EE05DC928EFF} -}; - -CMPlugin::CMPlugin() : - ACCPROTOPLUGIN(ICQ_PROTOCOL_NAME, pluginInfoEx) -{ - SetUniqueId(UNIQUEIDSETTING); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = { MIID_PROTOCOL, MIID_LAST }; - -///////////////////////////////////////////////////////////////////////////////////////// - -CMPlugin g_plugin; - -///////////////////////////////////////////////////////////////////////////////////////// - -int ModuleLoad(WPARAM, LPARAM) -{ - bPopupService = ServiceExists(MS_POPUP_ADDPOPUPT); - return 0; -} - -IconItem iconList[] = -{ - { LPGEN("Expand string edit"), "ICO_EXPANDSTRINGEDIT", IDI_EXPANDSTRINGEDIT } -}; - -int CMPlugin::Load() -{ - srand(time(0)); - _tzset(); - - // Initialize charset conversion routines - InitI18N(); - - // Register static services - CreateServiceFunction(ICQ_DB_GETEVENTTEXT_MISSEDMESSAGE, icq_getEventTextMissedMessage); - - // Init extra statuses - InitXStatusIcons(); - HookEvent(ME_SKIN2_ICONSCHANGED, OnReloadIcons); - - HookEvent(ME_SYSTEM_MODULELOAD, ModuleLoad); - HookEvent(ME_SYSTEM_MODULEUNLOAD, ModuleLoad); - - hExtraXStatus = ExtraIcon_RegisterIcolib("xstatus", LPGEN("ICQ xStatus"), "icq_xstatus13"); - - g_plugin.registerIcon("Protocols/ICQ", iconList); - - g_MenuInit(); - return 0; -} - -int CMPlugin::Unload() -{ - // destroying contact menu - g_MenuUninit(); - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// UpdateGlobalSettings event - -void CIcqProto::UpdateGlobalSettings() -{ - char szServer[MAX_PATH] = ""; - getSettingStringStatic(NULL, "OscarServer", szServer, MAX_PATH); - - m_bSecureConnection = getByte("SecureConnection", DEFAULT_SECURE_CONNECTION); - if (szServer[0]) { - if (strstr(szServer, "aol.com")) - setString("OscarServer", m_bSecureConnection ? DEFAULT_SERVER_HOST_SSL : DEFAULT_SERVER_HOST); - - if (m_bSecureConnection && !_strnicmp(szServer, "login.", 6)) { - setString("OscarServer", DEFAULT_SERVER_HOST_SSL); - setWord("OscarPort", DEFAULT_SERVER_PORT_SSL); - } - } - - if (m_hNetlibUser) { - NETLIBUSERSETTINGS nlus = { sizeof(NETLIBUSERSETTINGS) }; - if (!m_bSecureConnection && Netlib_GetUserSettings(m_hNetlibUser, &nlus)) { - if (nlus.useProxy && nlus.proxyType == PROXYTYPE_HTTP) - m_bGatewayMode = 1; - else - m_bGatewayMode = 0; - } - else m_bGatewayMode = 0; - } - - m_bSecureLogin = getByte("SecureLogin", DEFAULT_SECURE_LOGIN); - m_bLegacyFix = getByte("LegacyFix", DEFAULT_LEGACY_FIX); - m_wAnsiCodepage = getWord("AnsiCodePage", DEFAULT_ANSI_CODEPAGE); - m_bDCMsgEnabled = getByte("DirectMessaging", DEFAULT_DCMSG_ENABLED); - m_bTempVisListEnabled = getByte("TempVisListEnabled", DEFAULT_TEMPVIS_ENABLED); - m_bSsiEnabled = getByte("UseServerCList", DEFAULT_SS_ENABLED); - m_bSsiSimpleGroups = FALSE; /// TODO: enable, after server-list revolution is over - m_bAvatarsEnabled = getByte("AvatarsEnabled", DEFAULT_AVATARS_ENABLED); - m_bXStatusEnabled = getByte("XStatusEnabled", DEFAULT_XSTATUS_ENABLED); - m_bMoodsEnabled = getByte("MoodsEnabled", DEFAULT_MOODS_ENABLED); -} diff --git a/protocols/IcqOscarJ/src/log.cpp b/protocols/IcqOscarJ/src/log.cpp deleted file mode 100644 index 6639a7f796..0000000000 --- a/protocols/IcqOscarJ/src/log.cpp +++ /dev/null @@ -1,150 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2009 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -extern BOOL bPopupService; - -static const char *szLevelDescr[] = { LPGEN("ICQ Note"), LPGEN("ICQ Warning"), LPGEN("ICQ Error"), LPGEN("ICQ Fatal") }; - -struct LogMessageInfo -{ - const char *szMsg; - const char *szTitle; - BYTE bLevel; -}; - - -void __cdecl CIcqProto::icq_LogMessageThread(void* arg) -{ - LogMessageInfo *err = (LogMessageInfo*)arg; - if (!err) - return; - Thread_SetName("ICQ: LogMessageThread"); - - if (bPopupService && getByte("PopupsLogEnabled", DEFAULT_LOG_POPUPS_ENABLED)) { - ShowPopupMsg(NULL, err->szTitle, err->szMsg, err->bLevel); - - SAFE_FREE((void**)&err->szMsg); - SAFE_FREE((void**)&err); - - return; - } - - bErrorBoxVisible = TRUE; - if (err->szMsg && err->szTitle) - MessageBoxUtf(nullptr, err->szMsg, err->szTitle, MB_OK); - SAFE_FREE((void**)&err->szMsg); - SAFE_FREE((void**)&err); - bErrorBoxVisible = FALSE; -} - - -void CIcqProto::icq_LogMessage(int level, const char *szMsg) -{ - debugLogA("%s", szMsg); - - int displayLevel = getByte("ShowLogLevel", LOG_WARNING); - if (level >= displayLevel) { - if (!bErrorBoxVisible || !getByte("IgnoreMultiErrorBox", 0)) { - // error not shown or allowed multi - show messagebox - LogMessageInfo *lmi = (LogMessageInfo*)SAFE_MALLOC(sizeof(LogMessageInfo)); - lmi->bLevel = (BYTE)level; - lmi->szMsg = null_strdup(szMsg); - lmi->szTitle = szLevelDescr[level]; - ForkThread(&CIcqProto::icq_LogMessageThread, lmi); - } - } -} - -void CIcqProto::icq_LogUsingErrorCode(int level, DWORD dwError, const char *szMsg) -{ - char szBuf[1024]; - char str[1024]; - char str2[64]; - char szErrorMsg[512]; - char *pszErrorMsg = nullptr; - int bNeedFree = FALSE; - - switch (dwError) { - case ERROR_TIMEOUT: - case WSAETIMEDOUT: - pszErrorMsg = LPGEN("The server did not respond to the connection attempt within a reasonable time, it may be temporarily down. Try again later."); - break; - - case ERROR_GEN_FAILURE: - pszErrorMsg = LPGEN("The connection with the server was abortively closed during the connection attempt. You may have lost your local network connection."); - break; - - case WSAEHOSTUNREACH: - case WSAENETUNREACH: - pszErrorMsg = LPGEN("Miranda was unable to resolve the name of a server to its numeric address. This is most likely caused by a catastrophic loss of your network connection (for example, your modem has disconnected), but if you are behind a proxy, you may need to use the 'Resolve hostnames through proxy' option in Options -> Network."); - break; - - case WSAEHOSTDOWN: - case WSAENETDOWN: - case WSAECONNREFUSED: - pszErrorMsg = LPGEN("Miranda was unable to make a connection with a server. It is likely that the server is down, in which case you should wait for a while and try again later."); - break; - - case ERROR_ACCESS_DENIED: - pszErrorMsg = LPGEN("Your proxy rejected the user name and password that you provided. Please check them in Options -> Network."); - break; - - case WSAHOST_NOT_FOUND: - case WSANO_DATA: - pszErrorMsg = LPGEN("The server to which you are trying to connect does not exist. Check your spelling in Options -> Network -> ICQ."); - break; - - default: - wchar_t err[512]; - if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, dwError, 0, err, _countof(err), nullptr)) { - pszErrorMsg = make_utf8_string(err); - bNeedFree = TRUE; - } - break; - } - - mir_snprintf(szBuf, "%s%s%s (%s %d)", - szMsg ? ICQTranslateUtfStatic(szMsg, str, 1024) : "", - szMsg ? "\r\n\r\n" : "", - ICQTranslateUtfStatic(pszErrorMsg, szErrorMsg, 512), - ICQTranslateUtfStatic(LPGEN("error"), str2, 64), - dwError); - - if (bNeedFree) - SAFE_FREE(&pszErrorMsg); - - icq_LogMessage(level, szBuf); -} - -void CIcqProto::icq_LogFatalParam(const char *szMsg, WORD wError) -{ - char str[MAX_PATH]; - char buf[MAX_PATH]; - - mir_snprintf(buf, ICQTranslateUtfStatic(szMsg, str, _countof(str)), wError); - icq_LogMessage(LOG_FATAL, buf); -} diff --git a/protocols/IcqOscarJ/src/log.h b/protocols/IcqOscarJ/src/log.h deleted file mode 100644 index cc2223b0ca..0000000000 --- a/protocols/IcqOscarJ/src/log.h +++ /dev/null @@ -1,34 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2008 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// ----------------------------------------------------------------------------- - -#ifndef __LOG_H -#define __LOG_H - -#define LOG_NOTE 0 //trivial problems or problems that will already have been reported elsewhere -#define LOG_WARNING 1 //problems that may have caused data loss -#define LOG_ERROR 2 //problems that cause a disconnection from the network -#define LOG_FATAL 3 //problems requiring user intervention: password wrong, rate exceeded, etc. - -#endif /* __LOG_H */ diff --git a/protocols/IcqOscarJ/src/loginpassword.cpp b/protocols/IcqOscarJ/src/loginpassword.cpp deleted file mode 100644 index 6b897cf8de..0000000000 --- a/protocols/IcqOscarJ/src/loginpassword.cpp +++ /dev/null @@ -1,88 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2009 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -INT_PTR CALLBACK LoginPasswdDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - CIcqProto* ppro = (CIcqProto*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - - switch (msg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - - ppro = (CIcqProto*)lParam; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam); - - Window_SetIcon_IcoLib(hwndDlg, ppro->m_hProtoIcon); - { - DWORD dwUin = ppro->getContactUin(NULL); - - wchar_t pszUIN[MAX_PATH]; - mir_snwprintf(pszUIN, TranslateT("Enter a password for UIN %u:"), dwUin); - SetDlgItemText(hwndDlg, IDC_INSTRUCTION, pszUIN); - - SendDlgItemMessage(hwndDlg, IDC_LOGINPW, EM_LIMITTEXT, PASSWORDMAXLEN, 0); - - CheckDlgButton(hwndDlg, IDC_SAVEPASS, ppro->getByte("RememberPass", 0) ? BST_CHECKED : BST_UNCHECKED); - } - break; - - case WM_DESTROY: - Window_FreeIcon_IcoLib(hwndDlg); - break; - - case WM_CLOSE: - EndDialog(hwndDlg, 0); - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDOK: - ppro->m_bRememberPwd = (BYTE)IsDlgButtonChecked(hwndDlg, IDC_SAVEPASS); - ppro->setByte("RememberPass", ppro->m_bRememberPwd); - - GetDlgItemTextA(hwndDlg, IDC_LOGINPW, ppro->m_szPassword, _countof(ppro->m_szPassword)); - - ppro->icq_login(ppro->m_szPassword); - - EndDialog(hwndDlg, IDOK); - break; - - case IDCANCEL: - ppro->SetCurrentStatus(ID_STATUS_OFFLINE); - EndDialog(hwndDlg, IDCANCEL); - break; - } - break; - } - - return FALSE; -} - -void CIcqProto::RequestPassword() -{ - DialogBoxParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_LOGINPW), nullptr, LoginPasswdDlgProc, LPARAM(this)); -} diff --git a/protocols/IcqOscarJ/src/oscar_filetransfer.cpp b/protocols/IcqOscarJ/src/oscar_filetransfer.cpp deleted file mode 100644 index 7065e8837b..0000000000 --- a/protocols/IcqOscarJ/src/oscar_filetransfer.cpp +++ /dev/null @@ -1,2116 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// OSCAR File-Transfers implementation -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -struct oscarthreadstartinfo -{ - int type; - int incoming; - MCONTACT hContact; - HNETLIBCONN hConnection; - DWORD dwRemoteIP; - oscar_filetransfer *ft; - oscar_listener *listener; -}; - -// small utility function -extern void NormalizeBackslash(char* path); - -// -// Common functions -///////////////////////////// - -char* FindFilePathContainer(const char **files, int iFile, char *szContainer) -{ - const char *szThisFile = files[iFile]; - char *szFileName = (char*)ExtractFileName(szThisFile); - - szContainer[0] = '\0'; - - if (szThisFile != szFileName) { // find an earlier subdirectory to be used as a container - for (int i = iFile - 1; i >= 0; i--) { - size_t len = mir_strlen(files[i]); - if (!_strnicmp(files[i], szThisFile, len) && (szThisFile[len] == '\\' || szThisFile[len] == '/')) { - const char *pszLastBackslash; - - if (((pszLastBackslash = strrchr(files[i], '\\')) == nullptr) && - ((pszLastBackslash = strrchr(files[i], '/')) == nullptr)) { - mir_strcpy(szContainer, files[i]); - } - else { - len = pszLastBackslash - files[i] + 1; - null_strcpy(szContainer, szThisFile + len, szFileName - szThisFile - len); - } - } - } - } - return szFileName; -} - -// -// Utility functions -///////////////////////////// - -oscar_filetransfer* CIcqProto::CreateOscarTransfer() -{ - oscar_filetransfer *ft = (oscar_filetransfer*)SAFE_MALLOC(sizeof(oscar_filetransfer)); - ft->ft_magic = FT_MAGIC_OSCAR; // Setup signature - // Init members - ft->fileId = -1; - { - mir_cslock l(oftMutex); - m_arFileTransfers.insert(ft); - } - - NetLog_Direct("OFT: FT struct %p created", ft); - return ft; -} - -filetransfer* CIcqProto::CreateIcqFileTransfer() -{ - filetransfer *ft = (filetransfer*)SAFE_MALLOC(sizeof(filetransfer)); - ft->ft_magic = FT_MAGIC_ICQ; - { - mir_cslock l(oftMutex); - m_arFileTransfers.insert(ft); - } - - NetLog_Direct("FT struct %p created", ft); - return ft; -} - -int CIcqProto::IsValidFileTransfer(basic_filetransfer *ft) -{ - mir_cslock l(oftMutex); - return m_arFileTransfers.indexOf(ft) != -1; -} - -int CIcqProto::IsValidOscarTransfer(basic_filetransfer *ft) -{ - mir_cslock l(oftMutex); - return m_arFileTransfers.indexOf(ft) != -1 && ft->ft_magic == FT_MAGIC_OSCAR; -} - -oscar_filetransfer* CIcqProto::FindOscarTransfer(MCONTACT hContact, DWORD dwID1, DWORD dwID2) -{ - mir_cslock l(oftMutex); - - for (auto &it : m_arFileTransfers) { - if (it->ft_magic == FT_MAGIC_OSCAR) { - oscar_filetransfer *oft = (oscar_filetransfer*)it; - if (oft->hContact == hContact && oft->pMessage.dwMsgID1 == dwID1 && oft->pMessage.dwMsgID2 == dwID2) - return oft; - } - } - - return nullptr; -} - -// Release file transfer structure -void CIcqProto::SafeReleaseFileTransfer(basic_filetransfer **bft) -{ - mir_cslock l(oftMutex); - - // Check for filetransfer validity - int idx = m_arFileTransfers.indexOf(*bft); - if (idx == -1) - return; - - if (*bft) { - if ((*bft)->ft_magic == FT_MAGIC_ICQ) { // release ICQ filetransfer structure and its contents - filetransfer *ift = (filetransfer*)(*bft); - - SAFE_FREE(&ift->szFilename); - SAFE_FREE(&ift->szDescription); - SAFE_FREE(&ift->szSavePath); - SAFE_FREE(&ift->szThisSubdir); - if (ift->pszFiles) { - for (int i = 0; i < (int)ift->dwFileCount; i++) { - // szThisFile can be a duplicate of pszFiles[i] - if (ift->szThisFile == ift->pszFiles[i]) - ift->szThisFile = nullptr; - SAFE_FREE(&ift->pszFiles[i]); - } - SAFE_FREE((void**)&ift->pszFiles); - } - SAFE_FREE(&ift->szThisFile); - // Invalidate transfer - m_arFileTransfers.remove(idx); - - NetLog_Direct("FT struct %p released", bft); - - // Release memory - SAFE_FREE((void**)bft); - } - else if ((*bft)->ft_magic == FT_MAGIC_OSCAR) { // release oscar filetransfer structure and its contents - oscar_filetransfer *oft = (oscar_filetransfer*)(*bft); - // If connected, close connection - if (oft->connection) - CloseOscarConnection(oft->connection); - // Release oscar listener - if (oft->listener) - ReleaseOscarListener((oscar_listener**)&oft->listener); - // Release cookie - if (oft->dwCookie) - FreeCookie(oft->dwCookie); - // Release all dynamic members - SAFE_FREE(&oft->rawFileName); - SAFE_FREE(&oft->szSavePath); - SAFE_FREE(&oft->szThisFile); - SAFE_FREE(&oft->szThisPath); - SAFE_FREE(&oft->szDescription); - - if (oft->files) { - for (int i = 0; i < oft->wFilesCount; i++) - SAFE_FREE(&oft->files[i].szFile); - SAFE_FREE((void**)&oft->files); - } - - if (oft->files_list) - SAFE_FREE((void**)&oft->files_list); - - if (oft->file_containers) { - for (int i = 0; i < oft->containerCount; i++) - SAFE_FREE(&oft->file_containers[i]); - SAFE_FREE((void**)&oft->file_containers); - } - - if (oft->fileId != -1) - _close(oft->fileId); - - // Invalidate transfer - m_arFileTransfers.remove(idx); - - NetLog_Direct("OFT: FT struct %p released", bft); - - // Release memory - SAFE_FREE((void**)bft); - } - } -} - -// Calculate oft checksum of buffer -// -------------------------------- -// Information was gathered from Gaim's sources, thanks -// -DWORD oft_calc_checksum(int offset, const BYTE *buffer, int len, DWORD dwChecksum) -{ - DWORD checksum = (dwChecksum >> 16) & 0xffff; - - for (int i = 0; i < len; i++) { - WORD val = buffer[i]; - - if (((i + offset) & 1) == 0) - val = val << 8; - - if (checksum < val) - checksum -= val + 1; - else // simulate carry - checksum -= val; - } - checksum = ((checksum & 0x0000ffff) + (checksum >> 16)); - checksum = ((checksum & 0x0000ffff) + (checksum >> 16)); - return checksum << 16; -} - -DWORD oft_calc_file_checksum(int hFile, __int64 maxSize) -{ - BYTE buf[OFT_BUFFER_SIZE]; - int bytesRead; - __int64 offset = 0; - DWORD dwCheck = 0xFFFF0000; - - _lseek(hFile, 0, SEEK_SET); - bytesRead = _read(hFile, buf, (maxSize < sizeof(buf)) ? maxSize : (unsigned)sizeof(buf)); - if (bytesRead == -1) - return dwCheck; - - while (bytesRead) { - dwCheck = oft_calc_checksum((int)offset, buf, bytesRead, dwCheck); - offset += bytesRead; - bytesRead = _read(hFile, buf, sizeof(buf)); - if (bytesRead + offset > maxSize) bytesRead = (int)(maxSize - offset); - } - _lseek(hFile, 0, SEEK_SET); // back to beginning - - return dwCheck; -} - -oscar_listener* CIcqProto::CreateOscarListener(oscar_filetransfer *ft, NETLIBNEWCONNECTIONPROC_V2 handler) -{ - oscar_listener *listener = (oscar_listener*)SAFE_MALLOC(sizeof(oscar_listener)); - if (listener) { - listener->ppro = this; - listener->ft = ft; - if (listener->hBoundPort = NetLib_BindPort(handler, listener, &listener->wPort, nullptr)) - return listener; // Success - - SAFE_FREE((void**)&listener); - } - - return nullptr; // Failure -} - - -void CIcqProto::ReleaseOscarListener(oscar_listener **pListener) -{ - oscar_listener *listener = *pListener; - if (listener) { // Close listening port - if (listener->hBoundPort) { - Netlib_CloseHandle(listener->hBoundPort); - listener->hBoundPort = nullptr; - } - - NetLog_Direct("Oscar listener on port %d released.", listener->wPort); - } - SAFE_FREE((void**)pListener); -} - - -// -// Miranda FT interface handlers & services -///////////////////////////// - -void CIcqProto::handleRecvServMsgOFT(BYTE *buf, size_t wLen, DWORD dwUin, char *szUID, DWORD dwID1, DWORD dwID2, WORD wCommand) -{ - MCONTACT hContact = HContactFromUID(dwUin, szUID, nullptr); - - if (wCommand == 0) { // this is OFT request - oscar_tlv_chain* chain = readIntoTLVChain(&buf, wLen, 0); - - if (chain) { - WORD wAckType = chain->getWord(0x0A, 1); - - if (wAckType == 1) { // This is first request in this OFT - oscar_filetransfer *ft = CreateOscarTransfer(); - char *pszFileName = nullptr; - char *pszDescription = nullptr; - - debugLogA("This is a file request"); - - // This TLV chain may contain the following TLVs: - // TLV(A): Acktype 0x0001 - file request / abort request - // 0x0002 - file ack - // TLV(F): Unknown - // TLV(E): Language ? - // TLV(2): Proxy IP - // TLV(16): Proxy IP Check - // TLV(3): External IP - // TLV(4): Internal IP - // TLV(5): Port - // TLV(17): Port Check - // TLV(10): Proxy Flag - // TLV(D): Charset of User Message - // TLV(C): User Message (ICQ_COOL_FT) - // TLV(2711): FT info - // TLV(2712): Charset of file name - - // init filetransfer structure - ft->pMessage.dwMsgID1 = dwID1; - ft->pMessage.dwMsgID2 = dwID2; - ft->bUseProxy = chain->getTLV(0x10, 1) ? 1 : 0; - ft->dwProxyIP = chain->getDWord(0x02, 1); - ft->dwRemoteInternalIP = chain->getDWord(0x03, 1); - ft->dwRemoteExternalIP = chain->getDWord(0x04, 1); - ft->wRemotePort = chain->getWord(0x05, 1); - ft->wReqNum = wAckType; - - { // User Message - oscar_tlv* tlv = chain->getTLV(0x0C, 1); - - if (tlv) { // parse User Message - BYTE* tBuf = tlv->pData; - - pszDescription = (char*)_alloca(tlv->wLen + 2); - unpackString(&tBuf, (char*)pszDescription, tlv->wLen); - pszDescription[tlv->wLen] = '\0'; - pszDescription[tlv->wLen + 1] = '\0'; - { // apply User Message encoding - oscar_tlv *charset = chain->getTLV(0x0D, 1); - char *str = pszDescription; - char *bTag, *eTag; - - if (charset) { // decode charset - char *szEnc = (char*)_alloca(charset->wLen + 1); - - null_strcpy(szEnc, (char*)charset->pData, charset->wLen); - str = ApplyEncoding((char*)pszDescription, szEnc); - } - else str = null_strdup(str); - - // eliminate HTML tags - pszDescription = EliminateHtml(str, mir_strlen(str)); - - bTag = strstrnull(pszDescription, ""); - if (bTag) { // take special Description - ICQJ's extension - eTag = strstrnull(bTag, ""); - if (eTag) { - *eTag = '\0'; - str = null_strdup(bTag + 6); - SAFE_FREE(&pszDescription); - pszDescription = str; - } - } - else { - bTag = strstrnull(pszDescription, ""); - if (bTag) { // take only - Description tag if present - eTag = strstrnull(bTag, ""); - if (eTag) { - *eTag = '\0'; - str = null_strdup(bTag + 4); - SAFE_FREE(&pszDescription); - pszDescription = str; - } - } - } - } - } - if (!mir_strlen(pszDescription)) { - SAFE_FREE(&pszDescription); - pszDescription = ICQTranslateUtf(LPGEN("No description given")); - } - } - { // parse File Transfer Info block - oscar_tlv* tlv = chain->getTLV(0x2711, 1); - - // sanity check - if (!tlv || tlv->wLen < 8) { - debugLogA("Error: Malformed file request"); - // release structures - SafeReleaseFileTransfer((basic_filetransfer**)&ft); - SAFE_FREE(&pszDescription); - return; - } - - BYTE *tBuf = tlv->pData; - size_t tLen = tlv->wLen; - WORD wFlag; - - unpackWord(&tBuf, &wFlag); // FT flag - unpackWord(&tBuf, &ft->wFilesCount); - unpackDWord(&tBuf, (DWORD*)&ft->qwTotalSize); - tLen -= 8; - // Filename / Directory Name - if (tLen) { // some filename specified, unpack - size_t wFilenameLength = tLen - 1; - pszFileName = (char*)_alloca(tLen); - unpackString(&tBuf, (char*)pszFileName, wFilenameLength); - pszFileName[wFilenameLength] = '\0'; - } - else if (ft->wFilesCount == 1) // give some generic file name - pszFileName = "unnamed_file"; - else // or empty directory name - pszFileName = ""; - - // apply Filename / Directory Name encoding - oscar_tlv* charset = chain->getTLV(0x2712, 1); - if (charset) { - char* szEnc = (char*)_alloca(charset->wLen + 1); - null_strcpy(szEnc, (char*)charset->pData, charset->wLen); - pszFileName = ApplyEncoding(pszFileName, szEnc); - } - else pszFileName = ansi_to_utf8(pszFileName); - - if (ft->wFilesCount == 1) { // Filename - use for DB event - char *szFileName = (char*)_alloca(mir_strlen(pszFileName) + 1); - - mir_strcpy(szFileName, pszFileName); - SAFE_FREE(&pszFileName); - pszFileName = szFileName; - } - else { // Save Directory name for future use - ft->szThisPath = pszFileName; - // for multi-file transfer we do not display "folder" name, but create only a simple notice - pszFileName = (char*)_alloca(64); - - char tmp[64]; - mir_snprintf(pszFileName, 64, ICQTranslateUtfStatic(LPGEN("%d Files"), tmp, _countof(tmp)), ft->wFilesCount); - } - } - // Total Size TLV (ICQ 6 and AIM 6) - { - oscar_tlv *tlv = chain->getTLV(0x2713, 1); - - if (tlv && tlv->wLen >= 8) { - BYTE *tBuf = tlv->pData; - - unpackQWord(&tBuf, &ft->qwTotalSize); - } - } - int bAdded; - ft->hContact = HContactFromUID(dwUin, szUID, &bAdded); - ft->fileId = -1; - - // Send chain event - char *szBlob = (char*)_alloca(sizeof(DWORD) + mir_strlen(pszFileName) + mir_strlen(pszDescription) + 2); - *(PDWORD)szBlob = 0; - mir_strcpy(szBlob + sizeof(DWORD), pszFileName); - mir_strcpy(szBlob + sizeof(DWORD) + mir_strlen(pszFileName) + 1, pszDescription); - - wchar_t* ptszFileName = mir_utf8decodeW(pszFileName); - - PROTORECVFILE pre = { 0 }; - pre.dwFlags = PRFF_UNICODE; - pre.fileCount = 1; - pre.timestamp = time(0); - pre.descr.w = mir_utf8decodeW(pszDescription); - pre.files.w = &ptszFileName; - pre.lParam = (LPARAM)ft; - ProtoChainRecvFile(ft->hContact, &pre); - - mir_free(pre.descr.w); - mir_free(ptszFileName); - } - else if (wAckType == 2) { // First attempt failed, reverse requested - oscar_filetransfer *ft = FindOscarTransfer(hContact, dwID1, dwID2); - if (ft) { - NetLog_Direct("OFT: Redirect received (%d)", wAckType); - - ft->wReqNum = wAckType; - - if (ft->flags & OFTF_SENDING) { - ReleaseOscarListener((oscar_listener**)&ft->listener); - - ft->bUseProxy = chain->getTLV(0x10, 1) ? 1 : 0; - ft->dwProxyIP = chain->getDWord(0x02, 1); - ft->dwRemoteInternalIP = chain->getDWord(0x03, 1); - ft->dwRemoteExternalIP = chain->getDWord(0x04, 1); - ft->wRemotePort = chain->getWord(0x05, 1); - - OpenOscarConnection(hContact, ft, ft->bUseProxy ? OCT_PROXY_RECV : OCT_REVERSE); - } - else { // Just sanity - ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)ft, 0); - // Release transfer - SafeReleaseFileTransfer((basic_filetransfer**)&ft); - } - } - else debugLogA("Error: Invalid request, no such transfer"); - } - else if (wAckType == 3) { // Transfering thru proxy, join tunnel - oscar_filetransfer *ft = FindOscarTransfer(hContact, dwID1, dwID2); - if (ft) { // release possible previous listener - NetLog_Direct("OFT: Redirect received (%d)", wAckType); - - ft->wReqNum = wAckType; - - ReleaseOscarListener((oscar_listener**)&ft->listener); - - ft->bUseProxy = chain->getTLV(0x10, 1) ? 1 : 0; - ft->dwProxyIP = chain->getDWord(0x02, 1); - ft->wRemotePort = chain->getWord(0x05, 1); - - if (ft->bUseProxy && ft->dwProxyIP) // Init proxy connection - OpenOscarConnection(hContact, ft, OCT_PROXY_RECV); - else // try Stage 4 - OpenOscarConnection(hContact, ft, OCT_PROXY); - } - else debugLogA("Error: Invalid request, no such transfer"); - } - else if (wAckType == 4) { - oscar_filetransfer *ft = FindOscarTransfer(hContact, dwID1, dwID2); - if (ft) { - NetLog_Direct("OFT: Redirect received (%d)", wAckType); - - ft->wReqNum = wAckType; - ft->bUseProxy = chain->getTLV(0x10, 1) ? 1 : 0; - ft->dwProxyIP = chain->getDWord(0x02, 1); - ft->wRemotePort = chain->getWord(0x05, 1); - - if (ft->bUseProxy && ft->dwProxyIP) // Init proxy connection - OpenOscarConnection(hContact, ft, OCT_PROXY_RECV); - else - debugLogA("Error: Invalid request, IP missing."); - } - else debugLogA("Error: Invalid request, no such transfer"); - } - else debugLogA("Error: Uknown Stage %d request", wAckType); - - disposeChain(&chain); - } - else debugLogA("Error: Missing TLV chain in OFT request"); - } - else if (wCommand == 1) { // transfer cancelled/aborted - oscar_filetransfer *ft = FindOscarTransfer(hContact, dwID1, dwID2); - if (ft) { - debugLogA("OFT: File transfer cancelled by %s", strUID(dwUin, szUID)); - - ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)ft, 0); - // Notify user, that the FT was cancelled // TODO: new ACKRESULT_? - icq_LogMessage(LOG_ERROR, LPGEN("The file transfer was aborted by the other user.")); - // Release transfer - SafeReleaseFileTransfer((basic_filetransfer**)&ft); - } - else debugLogA("Error: Invalid request, no such transfer"); - } - else if (wCommand == 2) { // transfer accepted - connection established - oscar_filetransfer *ft = FindOscarTransfer(hContact, dwID1, dwID2); - - if (ft) { - NetLog_Direct("OFT: Session established."); - // Init connection - if (ft->flags & OFTF_SENDING) { - if (ft->connection && ft->connection->status == OCS_CONNECTED) { - if (!(ft->flags & OFTF_FILE_REQUEST_SENT)) { - ft->flags |= OFTF_FILE_REQUEST_SENT; - // proceed with first file - oft_sendPeerInit(ft->connection); - } - } - ft->flags |= OFTF_INITIALIZED; // accept was received - } - else debugLogA("Warning: Received invalid rendezvous accept"); - } - else debugLogA("Error: Invalid request, no such transfer"); - } - else debugLogA("Error: Unknown wCommand=0x%x in OFT request", wCommand); -} - -void CIcqProto::handleRecvServResponseOFT(BYTE *buf, size_t wLen, DWORD dwUin, char *szUID, void* ft) -{ - if (wLen < 2) - return; - - size_t wDataLen; - unpackWord(&buf, &wDataLen); - - if (wDataLen == 2) { - oscar_filetransfer *oft = (oscar_filetransfer*)ft; - - WORD wStatus; - unpackWord(&buf, &wStatus); - - switch (wStatus) { - case 1: - // FT denied (icq5) - debugLogA("OFT: File transfer denied by %s", strUID(dwUin, szUID)); - - ProtoBroadcastAck(oft->hContact, ACKTYPE_FILE, ACKRESULT_DENIED, (HANDLE)oft, 0); - // Release transfer - SafeReleaseFileTransfer((basic_filetransfer**)&oft); - break; - - case 4: // Proxy error - icq_LogMessage(LOG_ERROR, LPGEN("The file transfer failed: Proxy error")); - - ProtoBroadcastAck(oft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)oft, 0); - // Release transfer - SafeReleaseFileTransfer((basic_filetransfer**)&oft); - break; - - case 5: // Invalid request - icq_LogMessage(LOG_ERROR, LPGEN("The file transfer failed: Invalid request")); - - ProtoBroadcastAck(oft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)oft, 0); - // Release transfer - SafeReleaseFileTransfer((basic_filetransfer**)&oft); - break; - - case 6: // Proxy Failed (IP = 0) - icq_LogMessage(LOG_ERROR, LPGEN("The file transfer failed: Proxy unavailable")); - - ProtoBroadcastAck(oft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)oft, 0); - // Release transfer - SafeReleaseFileTransfer((basic_filetransfer**)&oft); - break; - - default: - debugLogA("OFT: Uknown request response code 0x%x", wStatus); - - ProtoBroadcastAck(oft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)oft, 0); - // Release transfer - SafeReleaseFileTransfer((basic_filetransfer**)&oft); - } - } -} - -// This function is called from the Netlib when someone is connecting to our oscar_listener -static void oft_newConnectionReceived(HNETLIBCONN hNewConnection, DWORD dwRemoteIP, void *pExtra) -{ - oscarthreadstartinfo *otsi = (oscarthreadstartinfo*)SAFE_MALLOC(sizeof(oscarthreadstartinfo)); - oscar_listener *listener = (oscar_listener*)pExtra; - - otsi->type = listener->ft->flags & OFTF_SENDING ? OCT_NORMAL : OCT_REVERSE; - otsi->incoming = 1; - otsi->hConnection = hNewConnection; - otsi->dwRemoteIP = dwRemoteIP; - otsi->listener = listener; - - // Start a new thread for the incomming connection - listener->ppro->ForkThread(&CIcqProto::oft_connectionThread, otsi); -} - -static char* oftGetFileContainer(oscar_filetransfer* oft, const char** files, int iFile) -{ - char szPath[MAX_PATH]; - FindFilePathContainer(files, iFile, szPath); - char *szPathUtf = ansi_to_utf8(szPath); - int i; - - // try to find existing container - for (i = 0; i < oft->containerCount; i++) - if (!mir_strcmp(szPathUtf, oft->file_containers[i])) { - SAFE_FREE((void**)&szPathUtf); - return oft->file_containers[i]; - } - - // create new container - i = oft->containerCount++; - oft->file_containers = (char**)SAFE_REALLOC(oft->file_containers, (sizeof(char*) * oft->containerCount)); - oft->file_containers[i] = szPathUtf; - - return oft->file_containers[i]; -} - - -HANDLE CIcqProto::oftInitTransfer(MCONTACT hContact, DWORD dwUin, char* szUid, const wchar_t** files, const wchar_t* pszDesc) -{ - int i, filesCount; - struct _stati64 statbuf; - - // Initialize filetransfer struct - debugLogA("Init file send"); - - oscar_filetransfer *ft = CreateOscarTransfer(); - ft->hContact = hContact; - ft->pMessage.bMessageType = MTYPE_FILEREQ; - InitMessageCookie(&ft->pMessage); - - for (filesCount = 0; files[filesCount]; filesCount++); - ft->files = (oft_file_record *)SAFE_MALLOC(sizeof(oft_file_record) * filesCount); - ft->files_list = (char**)SAFE_MALLOC(sizeof(wchar_t *) * filesCount); - ft->qwTotalSize = 0; - - char **filesUtf = (char**)SAFE_MALLOC(sizeof(char *) * filesCount); - for (i = 0; i < filesCount; i++) filesUtf[i] = FileNameToUtf(files[i]); - - // Prepare files arrays - for (i = 0; i < filesCount; i++) { - if (_wstat64(files[i], &statbuf)) - debugLogA("IcqSendFile() was passed invalid filename \"%s\"", files[i]); - else { - if (!(statbuf.st_mode & _S_IFDIR)) { // take only files - ft->files[ft->wFilesCount].szFile = ft->files_list[ft->wFilesCount] = null_strdup(filesUtf[i]); - ft->files[ft->wFilesCount].szContainer = oftGetFileContainer(ft, (LPCSTR*)filesUtf, i); - - ft->wFilesCount++; - ft->qwTotalSize += statbuf.st_size; - } - } - } - - for (i = 0; i < filesCount; i++) - SAFE_FREE(&filesUtf[i]); - SAFE_FREE((void**)&filesUtf); - - if (!ft->wFilesCount) { // found no valid files to send - icq_LogMessage(LOG_ERROR, LPGEN("Failed to Initialize File Transfer. No valid files were specified.")); - // Notify UI - ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)ft, 0); - - // Release transfer - SafeReleaseFileTransfer((basic_filetransfer**)&ft); - return nullptr; // Failure - } -#ifdef __GNUC__ -#define OSCAR_MAX_SIZE 0x100000000ULL -#else -#define OSCAR_MAX_SIZE 0x100000000 -#endif - if (ft->qwTotalSize >= OSCAR_MAX_SIZE && ft->wFilesCount > 1) { // file larger than 4GB can be send only as single - icq_LogMessage(LOG_ERROR, LPGEN("The files are too big to be sent at once. Files bigger than 4 GB can be sent only separately.")); - // Notify UI - ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)ft, 0); - - // Release transfer - SafeReleaseFileTransfer((basic_filetransfer**)&ft); - return nullptr; // Failure - } - - debugLogA("OFT: Found %d files.", ft->wFilesCount); - - ft->szDescription = make_utf8_string(pszDesc); - ft->flags = OFTF_SENDING; - ft->fileId = -1; - ft->iCurrentFile = 0; - ft->dwCookie = AllocateCookie(CKT_FILE, ICQ_MSG_SRV_SEND, hContact, ft); - - // Init oscar fields - { - ft->wEncrypt = 0; - ft->wCompress = 0; - ft->wPartsCount = 1; - ft->wPartsLeft = 1; - mir_strcpy(ft->rawIDString, "Cool FileXfer"); - ft->bHeaderFlags = 0x20; - ft->bNameOff = 0x1C; - ft->bSizeOff = 0x11; - ft->dwRecvForkCheck = 0xFFFF0000; - ft->dwThisForkCheck = 0xFFFF0000; - ft->dwRecvFileCheck = 0xFFFF0000; - } - - // Send file transfer request - { - char *pszFiles; - - if (ft->wFilesCount == 1) { // transfering single file, give filename - pszFiles = (char*)ExtractFileName(ft->files[0].szFile); - } - else { // check if transfering one directory - char *szFirstDiv, *szFirstDir = ft->file_containers[0]; - size_t nFirstDirLen; - - // default is no root dir - pszFiles = ""; - - if ((szFirstDiv = strstrnull(szFirstDir, "\\")) || (szFirstDiv = strstrnull(szFirstDir, "/"))) - nFirstDirLen = szFirstDiv - szFirstDir; - else - nFirstDirLen = mir_strlen(szFirstDir); - - if (nFirstDirLen) { // got root dir from first container, check if others are only sub-dirs - for (i = 0; i < ft->containerCount; i++) { - if (_strnicmp((char*)ft->file_containers[i], (char*)szFirstDir, nFirstDirLen)) { - szFirstDir = nullptr; - break; - } - } - if (szFirstDir) { // fine, we are sending only one directory - pszFiles = szFirstDir; - if (szFirstDiv) szFirstDiv[0] = '\0'; - nFirstDirLen++; // include backslash - // cut all files container by root dir - it is transferred as root separately - for (i = 0; i < ft->wFilesCount; i++) - ft->files[i].szContainer += nFirstDirLen; - } - } - } - - // Create listener - ft->listener = CreateOscarListener(ft, oft_newConnectionReceived); - - // Send packet - if (ft->listener) { - oft_sendFileRequest(dwUin, szUid, ft, pszFiles, getDword("RealIP", 0)); - } - else { // try stage 1 proxy - ft->szThisFile = null_strdup(pszFiles); - OpenOscarConnection(hContact, ft, OCT_PROXY_INIT); - } - } - - return ft; // Success -} - - -HANDLE CIcqProto::oftFileAllow(MCONTACT hContact, HANDLE hTransfer, const wchar_t *szPath) -{ - oscar_filetransfer *ft = (oscar_filetransfer*)hTransfer; - - DWORD dwUin; - uid_str szUid; - if (getContactUid(hContact, &dwUin, &szUid)) - return nullptr; // Invalid contact - - if (!IsValidOscarTransfer(ft)) - return nullptr; // Invalid transfer - - ft->szSavePath = make_utf8_string(szPath); - - if (ft->szThisPath) { // Append Directory name to the save path, when transfering a directory - ft->szSavePath = (char*)SAFE_REALLOC(ft->szSavePath, mir_strlen(ft->szSavePath) + mir_strlen(ft->szThisPath) + 4); - NormalizeBackslash(ft->szSavePath); - mir_strcat(ft->szSavePath, ft->szThisPath); - NormalizeBackslash(ft->szSavePath); - } - - NetLog_Direct("OFT: Request accepted, saving to '%s'.", ft->szSavePath); - - // Create cookie - ft->dwCookie = AllocateCookie(CKT_FILE, ICQ_MSG_SRV_SEND, hContact, ft); - - OpenOscarConnection(hContact, ft, ft->bUseProxy ? OCT_PROXY_RECV : OCT_NORMAL); - return hTransfer; // Success -} - -DWORD CIcqProto::oftFileDeny(MCONTACT hContact, HANDLE hTransfer, const wchar_t*) -{ - oscar_filetransfer *ft = (oscar_filetransfer*)hTransfer; - - DWORD dwUin; - uid_str szUid; - if (getContactUid(hContact, &dwUin, &szUid)) - return 1; // Invalid contact - - if (!IsValidOscarTransfer(ft)) - return 1; // Invalid transfer - - if (ft->hContact != hContact) - return 1; // Bad contact or hTransfer - - NetLog_Direct("OFT: Request denied."); - - oft_sendFileDeny(dwUin, szUid, ft); - - // Release structure - SafeReleaseFileTransfer((basic_filetransfer**)&ft); - return 0; // Success -} - -DWORD CIcqProto::oftFileCancel(MCONTACT hContact, HANDLE hTransfer) -{ - oscar_filetransfer* ft = (oscar_filetransfer*)hTransfer; - - DWORD dwUin; - uid_str szUid; - if (getContactUid(hContact, &dwUin, &szUid)) - return 1; // Invalid contact - - if (!IsValidOscarTransfer(ft)) - return 1; // Invalid transfer - - if (ft->hContact != hContact) - return 1; // Bad contact or hTransfer - - NetLog_Direct("OFT: Transfer cancelled."); - - oft_sendFileCancel(dwUin, szUid, ft); - - ProtoBroadcastAck(hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0); - - // Release structure - SafeReleaseFileTransfer((basic_filetransfer**)&ft); - - return 0; // Success -} - -void CIcqProto::oftFileResume(oscar_filetransfer *ft, int action, const wchar_t *szFilename) -{ - int openFlags; - - if (ft->connection == nullptr) - return; - - oscar_connection *oc = ft->connection; - - NetLog_Direct("OFT: Resume Transfer, Action: %d, FileName: '%s'", action, szFilename); - - switch (action) { - case FILERESUME_RESUME: - openFlags = _O_BINARY | _O_RDWR; - break; - - case FILERESUME_OVERWRITE: - openFlags = _O_BINARY | _O_CREAT | _O_TRUNC | _O_WRONLY; - ft->qwFileBytesDone = 0; - break; - - case FILERESUME_SKIP: - openFlags = _O_BINARY | _O_WRONLY; - ft->qwFileBytesDone = ft->qwThisFileSize; - break; - - case FILERESUME_RENAME: - openFlags = _O_BINARY | _O_CREAT | _O_TRUNC | _O_WRONLY; - SAFE_FREE(&ft->szThisFile); - ft->szThisFile = make_utf8_string(szFilename); - ft->qwFileBytesDone = 0; - break; - - default: // workaround for bug in Miranda Core - if (ft->resumeAction == FILERESUME_RESUME) - openFlags = _O_BINARY | _O_RDWR; - else { // default to overwrite - openFlags = _O_BINARY | _O_CREAT | _O_TRUNC | _O_WRONLY; - ft->qwFileBytesDone = 0; - } - } - ft->resumeAction = action; - - ft->fileId = OpenFileUtf(ft->szThisFile, openFlags, _S_IREAD | _S_IWRITE); - if (ft->fileId == -1) { - NetLog_Direct("OFT: errno=%d", errno); - - icq_LogMessage(LOG_ERROR, LPGEN("Your file receive has been aborted because Miranda could not open the destination file in order to write to it. You may be trying to save to a read-only folder.")); - - ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0); - // Release transfer - SafeReleaseFileTransfer((basic_filetransfer**)&oc->ft); - return; - } - - if (action == FILERESUME_RESUME) - ft->qwFileBytesDone = _lseeki64(ft->fileId, 0, SEEK_END); - else - _lseeki64(ft->fileId, ft->qwFileBytesDone, SEEK_SET); - - ft->qwBytesDone += ft->qwFileBytesDone; - - if (action == FILERESUME_RESUME) { // use smart-resume - oc->status = OCS_RESUME; - ft->dwRecvFileCheck = oft_calc_file_checksum(ft->fileId, ft->qwFileBytesDone); - _lseek(ft->fileId, 0, SEEK_END); - - NetLog_Direct("OFT: Starting Smart-Resume"); - - sendOFT2FramePacket(oc, OFT_TYPE_RESUMEREQUEST); - return; - } - - if (action == FILERESUME_SKIP) // we are skipping the file, send "we are done" - oc->status = OCS_NEGOTIATION; - - else { // Send "we are ready" - oc->status = OCS_DATA; - ft->flags |= OFTF_FILE_RECEIVING; - - sendOFT2FramePacket(oc, OFT_TYPE_READY); - } - ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ft, 0); - - if (!ft->qwThisFileSize || action == FILERESUME_SKIP) { // if the file is empty we will not receive any data - BYTE buf; - oft_handleFileData(oc, &buf, 0); - } -} - - -static void oft_buildProtoFileTransferStatus(oscar_filetransfer* ft, PROTOFILETRANSFERSTATUS* pfts) -{ - memset(pfts, 0, sizeof(PROTOFILETRANSFERSTATUS)); - pfts->hContact = ft->hContact; - pfts->flags = PFTS_UTF + ((ft->flags & OFTF_SENDING) ? PFTS_SENDING : PFTS_RECEIVING); - if (ft->flags & OFTF_SENDING) - pfts->pszFiles.a = ft->files_list; - else - pfts->pszFiles.a = nullptr; /* FIXME */ - pfts->totalFiles = ft->wFilesCount; - pfts->currentFileNumber = ft->iCurrentFile; - pfts->totalBytes = ft->qwTotalSize; - pfts->totalProgress = ft->qwBytesDone; - pfts->szWorkingDir.a = ft->szThisPath; - pfts->szCurrentFile.a = ft->szThisFile; - pfts->currentFileSize = ft->qwThisFileSize; - pfts->currentFileTime = ft->dwThisFileDate; - pfts->currentFileProgress = ft->qwFileBytesDone; -} - -void CIcqProto::CloseOscarConnection(oscar_connection *oc) -{ - mir_cslock l(oftMutex); - - if (oc) { - oc->type = OCT_CLOSING; - if (oc->hConnection) // we need this for Netlib handle consistency - NetLib_CloseConnection(&oc->hConnection, FALSE); - } -} - -///////////////////////////////////////////////////////////////////////////////////////// - -void CIcqProto::OpenOscarConnection(MCONTACT hContact, oscar_filetransfer *ft, int type) -{ - oscarthreadstartinfo *otsi = (oscarthreadstartinfo*)SAFE_MALLOC(sizeof(oscarthreadstartinfo)); - - otsi->hContact = hContact; - otsi->type = type; - otsi->ft = ft; - - ForkThread((MyThreadFunc)&CIcqProto::oft_connectionThread, otsi); -} - -int CIcqProto::CreateOscarProxyConnection(oscar_connection *oc) -{ - // inform UI - ProtoBroadcastAck(oc->ft->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTPROXY, oc->ft, 0); - - NETLIBOPENCONNECTION nloc = { 0 }; - nloc.szHost = OSCAR_PROXY_HOST; - nloc.wPort = getWord("OscarPort", m_bSecureConnection ? DEFAULT_SERVER_PORT_SSL : DEFAULT_SERVER_PORT); - if (nloc.wPort == 0) - nloc.wPort = RandRange(1024, 65535); - if (m_bGatewayMode) - nloc.flags |= NLOCF_HTTPGATEWAY; - - oc->hConnection = NetLib_OpenConnection(m_hNetlibUser, "Proxy ", &nloc); - if (!oc->hConnection) // proxy connection failed - return 0; - - oc->type = OCT_PROXY; - oc->status = OCS_PROXY; - oc->ft->connection = oc; - - // init proxy - proxy_sendInitTunnel(oc); - return 1; // Success -} - -void __cdecl CIcqProto::oft_connectionThread(void *param) -{ - Thread_SetName("ICQ: oft_connectionThread"); - - DWORD dwRemoteIP; - oscar_connection oc = {}; - oscar_listener *source; - { - oscarthreadstartinfo *otsi = (oscarthreadstartinfo*)param; - source = otsi->listener; - dwRemoteIP = otsi->dwRemoteIP; - - oc.hContact = otsi->hContact; - oc.hConnection = otsi->hConnection; - oc.type = otsi->type; - oc.incoming = otsi->incoming; - oc.ft = otsi->ft; - SAFE_FREE((void**)&otsi); - } - - if (oc.incoming) { - if (IsValidOscarTransfer(source->ft)) { - oc.ft = source->ft; - oc.ft->dwRemoteExternalIP = dwRemoteIP; - oc.hContact = oc.ft->hContact; - oc.ft->connection = &oc; - oc.status = OCS_CONNECTED; - } - else { // FT is already over, kill listener - NetLog_Direct("Received unexpected connection, closing."); - - CloseOscarConnection(&oc); - ReleaseOscarListener(&source); - return; - } - } - - if (oc.hContact) // Load contact information - getContactUid(oc.hContact, &oc.dwUin, &oc.szUid); - - // Load local IP information - oc.dwLocalExternalIP = getDword("IP", 0); - oc.dwLocalInternalIP = getDword("RealIP", 0); - - if (!oc.incoming) { // create outgoing connection - if (oc.type == OCT_NORMAL || oc.type == OCT_REVERSE) { // create outgoing connection to peer - NETLIBOPENCONNECTION nloc = { 0 }; - IN_ADDR addr = { 0 }, addr2 = { 0 }; - - if (oc.ft->dwRemoteExternalIP == oc.dwLocalExternalIP && oc.ft->dwRemoteInternalIP) - addr.S_un.S_addr = htonl(oc.ft->dwRemoteInternalIP); - else if (oc.ft->dwRemoteExternalIP) { - addr.S_un.S_addr = htonl(oc.ft->dwRemoteExternalIP); - // for different internal, try it also (for LANs with multiple external IP, VPNs, etc.) - if (oc.ft->dwRemoteInternalIP != oc.ft->dwRemoteExternalIP) - addr2.S_un.S_addr = htonl(oc.ft->dwRemoteInternalIP); - } - else // try LAN - addr.S_un.S_addr = htonl(oc.ft->dwRemoteInternalIP); - - // Inform UI that we will attempt to connect - ProtoBroadcastAck(oc.ft->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTING, oc.ft, 0); - - if (!addr.S_un.S_addr && oc.type == OCT_NORMAL) { // IP to connect to is empty, request reverse - oscar_listener* listener = CreateOscarListener(oc.ft, oft_newConnectionReceived); - - if (listener) { // we got listening port, fine send request - oc.ft->listener = listener; - // notify UI - ProtoBroadcastAck(oc.ft->hContact, ACKTYPE_FILE, ACKRESULT_LISTENING, oc.ft, 0); - - oft_sendFileRedirect(oc.dwUin, oc.szUid, oc.ft, oc.dwLocalInternalIP, listener->wPort, FALSE); - return; - } - if (!CreateOscarProxyConnection(&oc)) { // normal connection failed, notify peer, wait for error or stage 3 proxy - oft_sendFileRedirect(oc.dwUin, oc.szUid, oc.ft, 0, 0, FALSE); - // stage 3 can follow - return; - } - } - else if (addr.S_un.S_addr && oc.ft->wRemotePort) { - nloc.szHost = inet_ntoa(addr); - nloc.wPort = oc.ft->wRemotePort; - nloc.timeout = 8; // 8 secs to connect - oc.hConnection = NetLib_OpenConnection(m_hDirectNetlibUser, oc.type == OCT_REVERSE ? "Reverse " : nullptr, &nloc); - if (!oc.hConnection && addr2.S_un.S_addr) { // first address failed, try second one if available - nloc.szHost = inet_ntoa(addr2); - oc.hConnection = NetLib_OpenConnection(m_hDirectNetlibUser, oc.type == OCT_REVERSE ? "Reverse " : nullptr, &nloc); - } - if (!oc.hConnection) { - if (oc.type == OCT_NORMAL) { // connection failed, try reverse - oscar_listener* listener = CreateOscarListener(oc.ft, oft_newConnectionReceived); - - if (listener) { // we got listening port, fine send request - oc.ft->listener = listener; - // notify UI that we await connection - ProtoBroadcastAck(oc.ft->hContact, ACKTYPE_FILE, ACKRESULT_LISTENING, oc.ft, 0); - - oft_sendFileRedirect(oc.dwUin, oc.szUid, oc.ft, oc.dwLocalInternalIP, listener->wPort, FALSE); - return; - } - } - if (!CreateOscarProxyConnection(&oc)) { // proxy connection failed, notify peer, wait for error or stage 4 proxy - oft_sendFileRedirect(oc.dwUin, oc.szUid, oc.ft, 0, 0, FALSE); - // stage 3 or stage 4 can follow - return; - } - } - else { - oc.status = OCS_CONNECTED; - // ack normal connection - oc.ft->connection = &oc; - // acknowledge OFT - connection is ready - oft_sendFileAccept(oc.dwUin, oc.szUid, oc.ft); - // signal UI - ProtoBroadcastAck(oc.ft->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTED, oc.ft, 0); - } - } - else { // try proxy, stage 3 (sending) - if (!CreateOscarProxyConnection(&oc)) { // proxy connection failed, notify peer, wait for error or stage 4 proxy - oft_sendFileRedirect(oc.dwUin, oc.szUid, oc.ft, 0, 0, FALSE); - // stage 4 can follow - return; - } - } - } - else if (oc.type == OCT_PROXY_RECV) { // stage 2 & stage 4 - if (oc.ft->dwProxyIP && oc.ft->wRemotePort) { // create proxy connection, join tunnel - NETLIBOPENCONNECTION nloc = { 0 }; - IN_ADDR addr = { 0 }; - - // inform UI that we will connect to file proxy - ProtoBroadcastAck(oc.ft->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTPROXY, oc.ft, 0); - - addr.S_un.S_addr = htonl(oc.ft->dwProxyIP); - nloc.szHost = inet_ntoa(addr); - nloc.wPort = getWord("OscarPort", m_bSecureConnection ? DEFAULT_SERVER_PORT_SSL : DEFAULT_SERVER_PORT); - if (nloc.wPort == 0) - nloc.wPort = RandRange(1024, 65535); - if (m_bGatewayMode) - nloc.flags |= NLOCF_HTTPGATEWAY; - oc.hConnection = NetLib_OpenConnection(m_hNetlibUser, "Proxy ", &nloc); - if (!oc.hConnection) { // proxy connection failed, we are out of possibilities - ProtoBroadcastAck(oc.ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, oc.ft, 0); - // notify the other side, that we failed - oft_sendFileResponse(oc.dwUin, oc.szUid, oc.ft, 0x04); - // Release structure - SafeReleaseFileTransfer((basic_filetransfer**)&oc.ft); - return; - } - oc.status = OCS_PROXY; - oc.ft->connection = &oc; - // Join proxy tunnel - proxy_sendJoinTunnel(&oc, oc.ft->wRemotePort); - } - else // stage 2 failed (empty IP) - { // try stage 3, or send response error 0x06 - if (!CreateOscarProxyConnection(&oc)) { - oft_sendFileResponse(oc.dwUin, oc.szUid, oc.ft, 0x06); - // notify UI - ProtoBroadcastAck(oc.ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, oc.ft, 0); - // Release structure - SafeReleaseFileTransfer((basic_filetransfer**)&oc.ft); - return; - } - } - } - else if (oc.type == OCT_PROXY) { // stage 4 - if (!CreateOscarProxyConnection(&oc)) { // proxy connection failed, we are out of possibilities - ProtoBroadcastAck(oc.ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, oc.ft, 0); - // notify the other side, that we failed - oft_sendFileResponse(oc.dwUin, oc.szUid, oc.ft, 0x06); - // Release structure - SafeReleaseFileTransfer((basic_filetransfer**)&oc.ft); - return; - } - } - else if (oc.type == OCT_PROXY_INIT) { // stage 1 - if (!CreateOscarProxyConnection(&oc)) { // We failed to init transfer, notify UI - icq_LogMessage(LOG_ERROR, LPGEN("Failed to Initialize File Transfer. Unable to bind local port and File proxy unavailable.")); - // Release transfer - SafeReleaseFileTransfer((basic_filetransfer**)&oc.ft); - return; - } - else - oc.type = OCT_PROXY_INIT; - } - } - - if (!oc.hConnection) { // one more sanity check - NetLog_Direct("Error: No OFT connection."); - return; - } - - if (oc.status != OCS_PROXY) { // Connected, notify FT UI - ProtoBroadcastAck(oc.ft->hContact, ACKTYPE_FILE, ACKRESULT_INITIALISING, oc.ft, 0); - - // send init OFT frame - just for different order of packets (just like Trillian) - if (oc.status == OCS_CONNECTED && (oc.ft->flags & OFTF_SENDING) && ((oc.ft->flags & OFTF_INITIALIZED) || oc.type == OCT_REVERSE) && !(oc.ft->flags & OFTF_FILE_REQUEST_SENT)) { - oc.ft->flags |= OFTF_FILE_REQUEST_SENT; - // proceed with first file - oft_sendPeerInit(&oc); - } - } - - HANDLE hPacketRecver = Netlib_CreatePacketReceiver(oc.hConnection, 8192); - NETLIBPACKETRECVER packetRecv = {}; - - // Packet receiving loop - - while (oc.hConnection) { - packetRecv.dwTimeout = oc.wantIdleTime ? 0 : 120000; - - int recvResult = Netlib_GetMorePackets(hPacketRecver, &packetRecv); - if (!recvResult) { - NetLog_Direct("Clean closure of oscar socket (%p)", oc.hConnection); - break; - } - - if (recvResult == SOCKET_ERROR) { - if (GetLastError() == ERROR_TIMEOUT) { // TODO: this will not work on some systems - if (oc.wantIdleTime) { // here we want to send file data packets - oft_sendFileData(&oc); - } - else if (oc.status != OCS_WAITING) { - NetLog_Direct("Connection timeouted, closing."); - break; - } - } - else if (oc.type != OCT_CLOSING || GetLastError() != 87) { // log only significant errors, not "connection killed by us" - NetLog_Direct("Abortive closure of oscar socket (%p) (%d)", oc.hConnection, GetLastError()); - break; - } - } - - if (oc.type == OCT_CLOSING) - packetRecv.bytesUsed = packetRecv.bytesAvailable; - else - packetRecv.bytesUsed = oft_handlePackets(&oc, packetRecv.buffer, packetRecv.bytesAvailable); - } - - // End of packet receiving loop - - NetLib_SafeCloseHandle(&hPacketRecver); - - CloseOscarConnection(&oc); - - // Clean up - { - mir_cslock l(oftMutex); - if (m_arFileTransfers.indexOf(oc.ft) != -1) - oc.ft->connection = nullptr; // release link - } - // Give server some time for abort/cancel to arrive - SleepEx(1000, TRUE); - // Error handling - if (IsValidOscarTransfer(oc.ft)) { - if (oc.status == OCS_DATA) { - ProtoBroadcastAck(oc.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, oc.ft, 0); - - icq_LogMessage(LOG_ERROR, LPGEN("Connection lost during file transfer.")); - // Release structure - SafeReleaseFileTransfer((basic_filetransfer**)&oc.ft); - } - else if (oc.status == OCS_NEGOTIATION) { - ProtoBroadcastAck(oc.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, oc.ft, 0); - - icq_LogMessage(LOG_ERROR, LPGEN("File transfer negotiation failed for unknown reason.")); - // Release structure - SafeReleaseFileTransfer((basic_filetransfer**)&oc.ft); - } - } -} - -void CIcqProto::sendOscarPacket(oscar_connection *oc, icq_packet *packet) -{ - if (oc->hConnection) { - int nResult = Netlib_Send(oc->hConnection, (const char*)packet->pData, packet->wLen, 0); - if (nResult == SOCKET_ERROR) { - NetLog_Direct("Oscar %p socket error: %d, closing", oc->hConnection, GetLastError()); - CloseOscarConnection(oc); - } - } - - SAFE_FREE((void**)&packet->pData); -} - -int CIcqProto::oft_handlePackets(oscar_connection *oc, BYTE *buf, size_t len) -{ - size_t bytesUsed = 0; - - while (len > 0) { - if (oc->status == OCS_DATA && (oc->ft->flags & OFTF_FILE_RECEIVING)) - return oft_handleFileData(oc, buf, len); - - if (oc->status == OCS_PROXY) - return oft_handleProxyData(oc, buf, len); - - if (len < 6) - break; - - BYTE *pBuf = buf; - DWORD dwHead; - unpackDWord(&pBuf, &dwHead); - if (dwHead != 0x4F465432) { // bad packet - NetLog_Direct("OFT: Received invalid packet (dwHead = 0x%x).", dwHead); - - CloseOscarConnection(oc); - break; - } - - size_t datalen; - unpackWord(&pBuf, &datalen); - - if (len < datalen) // wait for whole packet - break; - - WORD datatype; - unpackWord(&pBuf, &datatype); -#ifdef _DEBUG - NetLog_Direct("OFT2: Type %u, Length %u bytes", datatype, datalen); -#endif - handleOFT2FramePacket(oc, datatype, pBuf, datalen - 8); - - /* Increase pointers so we can check for more data */ - buf += datalen; - len -= datalen; - bytesUsed += datalen; - } - - return (int)bytesUsed; -} - -int CIcqProto::oft_handleProxyData(oscar_connection *oc, BYTE *buf, size_t len) -{ - oscar_filetransfer *ft = oc->ft; - size_t datalen, bytesUsed = 0; - - while (len > 2) { - BYTE *pBuf = buf; - - unpackWord(&pBuf, &datalen); - datalen += 2; - - if (len < datalen) - break; // packet is not complete - - if (datalen < 12) { // malformed packet - CloseOscarConnection(oc); - break; - } - pBuf += 2; // packet version - - WORD wCommand; - unpackWord(&pBuf, &wCommand); - pBuf += 6; - - // handle packet - switch (wCommand) { - case 0x01: // Error - WORD wError; - char* szError; - - unpackWord(&pBuf, &wError); - switch (wError) { - case 0x0D: - szError = "Bad request"; - break; - case 0x0E: - szError = "Malformed packet"; - break; - case 0x10: - szError = "Initial request timeout"; - break; - case 0x1A: - szError = "Accept period timeout"; - break; - case 0x1C: - szError = "Invalid data"; - break; - - default: - szError = "Unknown"; - } - // Notify peer - oft_sendFileResponse(oc->dwUin, oc->szUid, oc->ft, 0x06); - - debugLogA("Proxy Error: %s (0x%x)", szError, wError); - // Notify UI - ProtoBroadcastAck(oc->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, oc->ft, 0); - // Release structure - SafeReleaseFileTransfer((basic_filetransfer**)&oc->ft); - break; - - case 0x03: // Tunnel created - WORD wCode; - DWORD dwIP; - - unpackWord(&pBuf, &wCode); - unpackDWord(&pBuf, &dwIP); - - if (oc->type == OCT_PROXY_INIT) { // Proxy ready, send Stage 1 Request - ft->bUseProxy = 1; - ft->wRemotePort = wCode; - ft->dwProxyIP = dwIP; - oft_sendFileRequest(oc->dwUin, oc->szUid, ft, ft->szThisFile, 0); - SAFE_FREE(&ft->szThisFile); - // Notify UI - ProtoBroadcastAck(oc->hContact, ACKTYPE_FILE, ACKRESULT_INITIALISING, oc->ft, 0); - } - else { - debugLogA("Proxy Tunnel ready, notify peer."); - oft_sendFileRedirect(oc->dwUin, oc->szUid, ft, dwIP, wCode, TRUE); - } - break; - - case 0x05: // Connection ready - oc->status = OCS_CONNECTED; // connection ready to send packets - // Notify UI - ProtoBroadcastAck(oc->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTED, oc->ft, 0); - // signal we are ready - if (oc->type == OCT_PROXY_RECV) { - oft_sendFileAccept(oc->dwUin, oc->szUid, ft); - if (ft->flags & OFTF_SENDING) // connection is ready for transfer (sending only) - ft->flags |= OFTF_INITIALIZED; - } - - debugLogA("Proxy Tunnel established"); - - if ((ft->flags & OFTF_INITIALIZED) && (ft->flags & OFTF_SENDING) && !(ft->flags & OFTF_FILE_REQUEST_SENT)) { - ft->flags |= OFTF_FILE_REQUEST_SENT; - // proceed with first file - oft_sendPeerInit(ft->connection); - } - break; - - default: - debugLogA("Unknown proxy command 0x%x", wCommand); - } - - buf += datalen; - len -= datalen; - bytesUsed += datalen; - } - - return (int)bytesUsed; -} - -int CIcqProto::oft_handleFileData(oscar_connection *oc, BYTE *buf, size_t len) -{ - oscar_filetransfer *ft = oc->ft; - size_t dwLen = len, bytesUsed = 0; - - // do not accept more data than expected - if (ft->qwThisFileSize - ft->qwFileBytesDone < dwLen) - dwLen = (int)(ft->qwThisFileSize - ft->qwFileBytesDone); - - if (ft->fileId == -1) { // something went terribly bad - CloseOscarConnection(oc); - return 0; - } - - _write(ft->fileId, buf, (unsigned)dwLen); - // update checksum - ft->dwRecvFileCheck = oft_calc_checksum((int)ft->qwFileBytesDone, buf, (unsigned)dwLen, ft->dwRecvFileCheck); - bytesUsed += dwLen; - ft->qwBytesDone += dwLen; - ft->qwFileBytesDone += dwLen; - - // notify FT UI of our progress, at most every 700ms - do not be faster than Miranda - if (GetTickCount() > ft->dwLastNotify + 700 || ft->qwFileBytesDone == ft->qwThisFileSize) { - PROTOFILETRANSFERSTATUS pfts; - oft_buildProtoFileTransferStatus(ft, &pfts); - ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_DATA, ft, (LPARAM)&pfts); - ft->dwLastNotify = GetTickCount(); - } - - if (ft->qwFileBytesDone == ft->qwThisFileSize) { - /* EOF */ - ft->flags &= ~OFTF_FILE_RECEIVING; - - _close(ft->fileId); - ft->fileId = -1; - - if (ft->resumeAction != FILERESUME_SKIP && ft->dwRecvFileCheck != ft->dwThisFileCheck) { - NetLog_Direct("Error: File checksums does not match!"); - - // Notify UI - char *pszMsg = ICQTranslateUtf(LPGEN("The checksum of file \"%s\" does not match, the file is probably damaged.")); - char szBuf[MAX_PATH]; - - mir_snprintf(szBuf, pszMsg, ExtractFileName(ft->szThisFile)); - icq_LogMessage(LOG_ERROR, szBuf); - - SAFE_FREE(&pszMsg); - } - // keep transfer going (icq6 ignores checksums completely) - else if (ft->resumeAction == FILERESUME_SKIP) - NetLog_Direct("OFT: File receive skipped."); - else - NetLog_Direct("OFT: File received successfully."); - - if ((DWORD)(ft->iCurrentFile + 1) == ft->wFilesCount) { - ft->bHeaderFlags = 0x01; // the whole process is over - // ack received file - sendOFT2FramePacket(oc, OFT_TYPE_DONE); - oc->type = OCT_CLOSING; - NetLog_Direct("File Transfer completed successfully."); - ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft, 0); - // Release transfer - SafeReleaseFileTransfer((basic_filetransfer**)&ft); - } - else { // ack received file - sendOFT2FramePacket(oc, OFT_TYPE_DONE); - oc->status = OCS_NEGOTIATION; - } - } - return (int)bytesUsed; -} - -void CIcqProto::handleOFT2FramePacket(oscar_connection *oc, WORD datatype, BYTE *pBuffer, size_t wLen) -{ - oscar_filetransfer *ft = oc->ft; - DWORD dwID1; - DWORD dwID2; - - if (wLen < 232) { // allow shorter packets, but at least with filename - NetLog_Direct("Error: Malformed OFT2 Frame, ignoring."); - return; - } - - unpackLEDWord(&pBuffer, &dwID1); - wLen -= 4; - unpackLEDWord(&pBuffer, &dwID2); - wLen -= 4; - - if (datatype == OFT_TYPE_REQUEST && !(ft->flags & OFTF_FILE_REQUEST_RECEIVED)) { // first request does not contain MsgIDs we need to send them in ready packet - dwID1 = ft->pMessage.dwMsgID1; - dwID2 = ft->pMessage.dwMsgID2; - } - - if (ft->pMessage.dwMsgID1 != dwID1 || ft->pMessage.dwMsgID2 != dwID2) { // this is not the right packet - bad Message IDs - NetLog_Direct("Error: Invalid Packet Cookie, closing."); - CloseOscarConnection(oc); - return; - } - - switch (datatype) { - - case OFT_TYPE_REQUEST: - // Sender ready - if (ft->flags & OFTF_SENDING) { // just sanity check - this is only for receiving client - NetLog_Direct("Error: Invalid Packet, closing."); - CloseOscarConnection(oc); - return; - } - - // Read Frame data - if (!(ft->flags & OFTF_FILE_REQUEST_RECEIVED)) { - unpackWord(&pBuffer, &ft->wEncrypt); - unpackWord(&pBuffer, &ft->wCompress); - unpackWord(&pBuffer, &ft->wFilesCount); - } - else - pBuffer += 6; - unpackWord(&pBuffer, &ft->wFilesLeft); - ft->iCurrentFile = ft->wFilesCount - ft->wFilesLeft; - if (!(ft->flags & OFTF_FILE_REQUEST_RECEIVED)) - unpackWord(&pBuffer, &ft->wPartsCount); - else - pBuffer += 2; - unpackWord(&pBuffer, &ft->wPartsLeft); - if (!(ft->flags & OFTF_FILE_REQUEST_RECEIVED)) { // just check it - DWORD dwSize; - - unpackDWord(&pBuffer, &dwSize); - if (dwSize != (DWORD)ft->qwTotalSize) { // the 32bits does not match, use them as full size - ft->qwTotalSize = dwSize; - debugLogA("Warning: Invalid total size."); - } - } - else pBuffer += 4; - - // this allows us to receive single >4GB file correctly - DWORD dwSize; - unpackDWord(&pBuffer, &dwSize); - if (dwSize == (DWORD)ft->qwTotalSize && ft->wFilesCount == 1) - ft->qwThisFileSize = ft->qwTotalSize; - else - ft->qwThisFileSize = dwSize; - - unpackDWord(&pBuffer, &ft->dwThisFileDate); - unpackDWord(&pBuffer, &ft->dwThisFileCheck); - unpackDWord(&pBuffer, &ft->dwRecvForkCheck); - unpackDWord(&pBuffer, &ft->dwThisForkSize); - unpackDWord(&pBuffer, &ft->dwThisFileCreation); - unpackDWord(&pBuffer, &ft->dwThisForkCheck); - pBuffer += 4; // File Bytes Done - unpackDWord(&pBuffer, &ft->dwRecvFileCheck); - if (!(ft->flags & OFTF_FILE_REQUEST_RECEIVED)) - unpackString(&pBuffer, ft->rawIDString, 32); - else - pBuffer += 32; - unpackByte(&pBuffer, &ft->bHeaderFlags); - unpackByte(&pBuffer, &ft->bNameOff); - unpackByte(&pBuffer, &ft->bSizeOff); - if (!(ft->flags & OFTF_FILE_REQUEST_RECEIVED)) { - unpackString(&pBuffer, (char*)ft->rawDummy, 69); - unpackString(&pBuffer, (char*)ft->rawMacInfo, 16); - } - else pBuffer += 85; - - unpackWord(&pBuffer, &ft->wEncoding); - unpackWord(&pBuffer, &ft->wSubEncoding); - ft->cbRawFileName = wLen - 176; - SAFE_FREE((void**)&ft->rawFileName); // release previous buffers - SAFE_FREE(&ft->szThisFile); - ft->rawFileName = (char*)SAFE_MALLOC(ft->cbRawFileName + 2); - unpackString(&pBuffer, ft->rawFileName, ft->cbRawFileName); - // Prepare file - if (ft->wEncoding == 2) // UCS-2 encoding - ft->szThisFile = ApplyEncoding(ft->rawFileName, "unicode-2-0"); - else - ft->szThisFile = ansi_to_utf8(ft->rawFileName); - - // convert dir markings to normal backslashes - for (size_t i = 0; i < mir_strlen(ft->szThisFile); i++) - if (ft->szThisFile[i] == 0x01) - ft->szThisFile[i] = '\\'; - - ft->flags |= OFTF_FILE_REQUEST_RECEIVED; // First Frame Processed - - NetLog_Direct("File '%s', %I64u Bytes", ft->szThisFile, ft->qwThisFileSize); - - { // Prepare Path Information - char *szFile = strrchr(ft->szThisFile, '\\'); - - SAFE_FREE(&ft->szThisPath); // release previous path - if (szFile) { - ft->szThisPath = ft->szThisFile; - szFile[0] = '\0'; // split that strings - ft->szThisFile = null_strdup(szFile + 1); - // no cheating with paths - if (!IsValidRelativePath(ft->szThisPath)) { - NetLog_Direct("Invalid path information"); - break; - } - } - else ft->szThisPath = null_strdup(""); - } - - /* no cheating with paths */ - if (!IsValidRelativePath(ft->szThisFile)) { - NetLog_Direct("Invalid path information"); - break; - } - - { - char *szFullPath = (char*)SAFE_MALLOC(mir_strlen(ft->szSavePath) + mir_strlen(ft->szThisPath) + mir_strlen(ft->szThisFile) + 3); - mir_strcpy(szFullPath, ft->szSavePath); - NormalizeBackslash(szFullPath); - mir_strcat(szFullPath, ft->szThisPath); - NormalizeBackslash(szFullPath); - // make sure the dest dir exists - if (MakeDirUtf(szFullPath)) - NetLog_Direct("Failed to create destination directory!"); - - mir_strcat(szFullPath, ft->szThisFile); - // we joined the full path to dest file - SAFE_FREE(&ft->szThisFile); - ft->szThisFile = szFullPath; - } - - ft->qwFileBytesDone = 0; - - /* file resume */ - PROTOFILETRANSFERSTATUS pfts; - oft_buildProtoFileTransferStatus(ft, &pfts); - if (ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_FILERESUME, ft, (LPARAM)&pfts)) { - oc->status = OCS_WAITING; - break; /* UI supports resume: it will call PS_FILERESUME */ - } - - ft->fileId = OpenFileUtf(ft->szThisFile, _O_BINARY | _O_CREAT | _O_TRUNC | _O_WRONLY, _S_IREAD | _S_IWRITE); -#ifdef _DEBUG - NetLog_Direct("OFT: OpenFileUtf(%s, %u) returned %u", ft->szThisFile, _O_BINARY | _O_CREAT | _O_TRUNC | _O_WRONLY, ft->fileId); -#endif - if (ft->fileId == -1) { -#ifdef _DEBUG - NetLog_Direct("OFT: errno=%d", errno); -#endif - icq_LogMessage(LOG_ERROR, LPGEN("Your file receive has been aborted because Miranda could not open the destination file in order to write to it. You may be trying to save to a read-only folder.")); - - ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0); - // Release transfer - SafeReleaseFileTransfer((basic_filetransfer**)&oc->ft); - return; - } - - // Send "we are ready" - oc->status = OCS_DATA; - ft->flags |= OFTF_FILE_RECEIVING; - - sendOFT2FramePacket(oc, OFT_TYPE_READY); - ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ft, 0); - if (!ft->qwThisFileSize) { // if the file is empty we will not receive any data - BYTE buf; - oft_handleFileData(oc, &buf, 0); - } - return; - - case OFT_TYPE_READY: - case OFT_TYPE_RESUMEACK: - // Receiver is ready - oc->status = OCS_DATA; - oc->wantIdleTime = 1; - ft->flags |= OFTF_FILE_SENDING; - - NetLog_Direct("OFT: Receiver ready."); - break; - - case OFT_TYPE_RESUMEREQUEST: - // Receiver wants to resume file transfer from point - if (!(ft->flags & OFTF_SENDING)) { // just sanity check - this is only for sending client - NetLog_Direct("Error: Invalid Packet, closing."); - CloseOscarConnection(oc); - return; - } - - DWORD dwResumeCheck, dwResumeOffset, dwFileCheck; - // Read Resume Frame data - pBuffer += 44; - unpackDWord(&pBuffer, &dwResumeOffset); - unpackDWord(&pBuffer, &dwResumeCheck); - - dwFileCheck = oft_calc_file_checksum(ft->fileId, dwResumeOffset); - if (dwFileCheck == dwResumeCheck && dwResumeOffset <= ft->qwThisFileSize) { // resume seems ok - ft->qwFileBytesDone = dwResumeOffset; - ft->qwBytesDone += dwResumeOffset; - _lseek(ft->fileId, dwResumeOffset, SEEK_SET); - - NetLog_Direct("OFT: Resume request, ready."); - } - else - NetLog_Direct("OFT: Resume request, restarting."); - - // Ready for resume - sendOFT2FramePacket(oc, OFT_TYPE_RESUMEREADY); - break; - - case OFT_TYPE_RESUMEREADY: - // Process Smart-resume reply - if (ft->flags & OFTF_SENDING) { // just sanity check - this is only for receiving client - NetLog_Direct("Error: Invalid Packet, closing."); - CloseOscarConnection(oc); - return; - } - - // Read Resume Reply data - pBuffer += 44; - unpackDWord(&pBuffer, &dwResumeOffset); - unpackDWord(&pBuffer, &dwResumeCheck); - - if (ft->qwFileBytesDone != dwResumeOffset) { - ft->qwBytesDone -= (ft->qwFileBytesDone - dwResumeOffset); - ft->qwFileBytesDone = dwResumeOffset; - if (dwResumeOffset) - ft->dwRecvFileCheck = dwResumeCheck; - else // Restarted resume (data mismatch) - ft->dwRecvFileCheck = 0xFFFF0000; - } - _lseek(ft->fileId, dwResumeOffset, SEEK_SET); - - if (ft->qwThisFileSize != ft->qwFileBytesDone) - NetLog_Direct("OFT: Resuming from offset %u.", dwResumeOffset); - - // Prepare to receive data - oc->status = OCS_DATA; - - ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ft, 0); - - // Ready for receive - sendOFT2FramePacket(oc, OFT_TYPE_RESUMEACK); - - if (ft->qwThisFileSize == ft->qwFileBytesDone) { // all data already processed - BYTE buf; - - oft_handleFileData(oc, &buf, 0); - } - break; - - case OFT_TYPE_DONE: - // File done - oc->status = OCS_NEGOTIATION; - oc->wantIdleTime = 0; - - ft->flags &= ~OFTF_FILE_SENDING; - - NetLog_Direct("OFT: File sent successfully."); - -#ifdef _DEBUG - NetLog_Direct("OFT: _close(%u)", ft->fileId); -#endif - _close(ft->fileId); // FIXME: this needs fix for "skip file" feature - ft->fileId = -1; - ft->iCurrentFile++; - // continue with next file - oft_sendPeerInit(oc); - break; - - default: - NetLog_Direct("Error: Uknown OFT frame type 0x%x", datatype); - } -} - -// -// Proxy packets -///////////////////////////// - -void CIcqProto::proxy_sendInitTunnel(oscar_connection *oc) -{ - icq_packet packet; - size_t wLen = 39 + getUINLen(m_dwLocalUIN); - - packet.wLen = WORD(wLen); - init_generic_packet(&packet, 2); - - packWord(&packet, WORD(wLen)); - packWord(&packet, OSCAR_PROXY_VERSION); - packWord(&packet, 0x02); // wCommand - packDWord(&packet, 0); // Unknown - packWord(&packet, 0); // Flags? - packUIN(&packet, m_dwLocalUIN); - packLEDWord(&packet, oc->ft->pMessage.dwMsgID1); - packLEDWord(&packet, oc->ft->pMessage.dwMsgID2); - packDWord(&packet, 0x00010010); // TLV(1) - packGUID(&packet, MCAP_FILE_TRANSFER); - - sendOscarPacket(oc, &packet); -} - -void CIcqProto::proxy_sendJoinTunnel(oscar_connection *oc, WORD wPort) -{ - icq_packet packet; - size_t wLen = 41 + getUINLen(m_dwLocalUIN); - - packet.wLen = WORD(wLen); - init_generic_packet(&packet, 2); - - packWord(&packet, WORD(wLen)); - packWord(&packet, OSCAR_PROXY_VERSION); - packWord(&packet, 0x04); // wCommand - packDWord(&packet, 0); // Unknown - packWord(&packet, 0); // Flags? - packUIN(&packet, m_dwLocalUIN); - packWord(&packet, wPort); - packLEDWord(&packet, oc->ft->pMessage.dwMsgID1); - packLEDWord(&packet, oc->ft->pMessage.dwMsgID2); - packDWord(&packet, 0x00010010); // TLV(1) - packGUID(&packet, MCAP_FILE_TRANSFER); - - sendOscarPacket(oc, &packet); -} - -// -// Direct packets -///////////////////////////// - -void CIcqProto::oft_sendFileData(oscar_connection *oc) -{ - oscar_filetransfer *ft = oc->ft; - BYTE buf[OFT_BUFFER_SIZE]; - - if (ft->fileId == -1) - return; - - int bytesRead = _read(ft->fileId, buf, sizeof(buf)); - if (bytesRead == -1) - return; - - if (!bytesRead) { // - oc->wantIdleTime = 0; - return; - } - - if ((DWORD)bytesRead > (ft->qwThisFileSize - ft->qwFileBytesDone)) { // do not send more than expected, limit to known size - bytesRead = (DWORD)(ft->qwThisFileSize - ft->qwFileBytesDone); - oc->wantIdleTime = 0; - } - - if (bytesRead) { - icq_packet packet; - packet.wLen = bytesRead; - init_generic_packet(&packet, 0); - packBuffer(&packet, buf, bytesRead); // we are sending raw data - sendOscarPacket(oc, &packet); - - ft->qwBytesDone += bytesRead; - ft->qwFileBytesDone += bytesRead; - } - - if (GetTickCount() > ft->dwLastNotify + 700 || oc->wantIdleTime == 0 || ft->qwFileBytesDone == ft->qwThisFileSize) { // notify only once a while or after last data packet sent - PROTOFILETRANSFERSTATUS pfts; - oft_buildProtoFileTransferStatus(ft, &pfts); - ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_DATA, ft, (LPARAM)&pfts); - ft->dwLastNotify = GetTickCount(); - } -} - -void CIcqProto::oft_sendPeerInit(oscar_connection *oc) -{ - mir_cslock l(oftMutex); - - // prepare init frame - oscar_filetransfer *ft = oc->ft; - if (ft->iCurrentFile >= (int)ft->wFilesCount) { // All files done, great! - ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft, 0); - // Release transfer - SafeReleaseFileTransfer((basic_filetransfer**)&oc->ft); - return; - } - - SAFE_FREE(&ft->szThisFile); - ft->szThisFile = null_strdup(ft->files[ft->iCurrentFile].szFile); - - struct _stati64 statbuf; - if (FileStatUtf(ft->szThisFile, &statbuf)) { - icq_LogMessage(LOG_ERROR, LPGEN("Your file transfer has been aborted because one of the files that you selected to send is no longer readable from the disk. You may have deleted or moved it.")); - - ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0); - // Release transfer - SafeReleaseFileTransfer((basic_filetransfer**)&oc->ft); - return; - } - - // create full relative filename - char* szThisContainer = ft->files[ft->iCurrentFile].szContainer; - - char *pszThisFileName = (char*)SAFE_MALLOC(mir_strlen(ft->szThisFile) + mir_strlen(szThisContainer) + 4); - mir_strcpy(pszThisFileName, szThisContainer); - NormalizeBackslash(pszThisFileName); - mir_strcat(pszThisFileName, ExtractFileName(ft->szThisFile)); - - // convert backslashes to dir markings - for (size_t i = 0; i < mir_strlen(pszThisFileName); i++) - if (pszThisFileName[i] == '\\' || pszThisFileName[i] == '/') - pszThisFileName[i] = 0x01; - - ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ft, 0); - - ft->fileId = OpenFileUtf(ft->szThisFile, _O_BINARY | _O_RDONLY, 0); - if (ft->fileId == -1) { - NetLog_Direct("OFT: error opening file %s, errno=%d", ft->szThisFile, errno); - SAFE_FREE((void**)&pszThisFileName); - icq_LogMessage(LOG_ERROR, LPGEN("Your file transfer has been aborted (error=%d), because one of the files that you selected to send is no longer readable from the disk. You may have deleted or moved it.")); - - ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0); - // Release transfer - SafeReleaseFileTransfer((basic_filetransfer**)&oc->ft); - return; - } - - ft->qwThisFileSize = statbuf.st_size; - ft->dwThisFileDate = statbuf.st_mtime; - ft->dwThisFileCreation = statbuf.st_ctime; - ft->dwThisFileCheck = oft_calc_file_checksum(ft->fileId, ft->qwThisFileSize); - ft->qwFileBytesDone = 0; - ft->dwRecvFileCheck = 0xFFFF0000; - SAFE_FREE((void**)&ft->rawFileName); - - if (IsUSASCII(pszThisFileName, mir_strlen(pszThisFileName))) { - ft->wEncoding = 0; // ascii - ft->cbRawFileName = WORD(mir_strlen(pszThisFileName) + 1); - if (ft->cbRawFileName < 64) - ft->cbRawFileName = 64; - ft->rawFileName = (char*)SAFE_MALLOC(ft->cbRawFileName); - mir_strcpy(ft->rawFileName, (char*)pszThisFileName); - SAFE_FREE((void**)&pszThisFileName); - } - else { - ft->wEncoding = 2; // ucs-2 - WCHAR *pwsThisFile = make_unicode_string(pszThisFileName); - SAFE_FREE((void**)&pszThisFileName); - ft->cbRawFileName = WORD(mir_wstrlen(pwsThisFile) * sizeof(WCHAR)) + 2; - if (ft->cbRawFileName < 64) - ft->cbRawFileName = 64; - ft->rawFileName = (char*)SAFE_MALLOC(ft->cbRawFileName); - // convert to LE ordered string - BYTE *pwsThisFileBuf = (BYTE*)pwsThisFile; // need this - unpackWideString moves the address! - unpackWideString(&pwsThisFileBuf, (WCHAR*)ft->rawFileName, mir_wstrlen(pwsThisFile) * sizeof(WCHAR)); - SAFE_FREE((void**)&pwsThisFile); - } - ft->wFilesLeft = WORD(ft->wFilesCount - ft->iCurrentFile); - - sendOFT2FramePacket(oc, OFT_TYPE_REQUEST); -} - -void CIcqProto::sendOFT2FramePacket(oscar_connection *oc, WORD datatype) -{ - oscar_filetransfer *ft = oc->ft; - - icq_packet packet; - packet.wLen = WORD(192 + ft->cbRawFileName); - init_generic_packet(&packet, 0); - - // Basic Oscar Frame - packDWord(&packet, 0x4F465432); // Magic - packWord(&packet, packet.wLen); - packWord(&packet, datatype); - - // Cookie - packLEDWord(&packet, ft->pMessage.dwMsgID1); - packLEDWord(&packet, ft->pMessage.dwMsgID2); - packWord(&packet, ft->wEncrypt); - packWord(&packet, ft->wCompress); - packWord(&packet, ft->wFilesCount); - packWord(&packet, ft->wFilesLeft); - packWord(&packet, ft->wPartsCount); - packWord(&packet, ft->wPartsLeft); - packDWord(&packet, (DWORD)ft->qwTotalSize); - packDWord(&packet, (DWORD)ft->qwThisFileSize); - packDWord(&packet, ft->dwThisFileDate); - packDWord(&packet, ft->dwThisFileCheck); - packDWord(&packet, ft->dwRecvForkCheck); - packDWord(&packet, ft->dwThisForkSize); - packDWord(&packet, ft->dwThisFileCreation); - packDWord(&packet, ft->dwThisForkCheck); - packDWord(&packet, (DWORD)ft->qwFileBytesDone); - packDWord(&packet, ft->dwRecvFileCheck); - packBuffer(&packet, (LPBYTE)ft->rawIDString, 32); - packByte(&packet, ft->bHeaderFlags); - packByte(&packet, ft->bNameOff); - packByte(&packet, ft->bSizeOff); - packBuffer(&packet, ft->rawDummy, 69); - packBuffer(&packet, ft->rawMacInfo, 16); - packWord(&packet, ft->wEncoding); - packWord(&packet, ft->wSubEncoding); - packBuffer(&packet, (LPBYTE)ft->rawFileName, ft->cbRawFileName); - - sendOscarPacket(oc, &packet); -} diff --git a/protocols/IcqOscarJ/src/oscar_filetransfer.h b/protocols/IcqOscarJ/src/oscar_filetransfer.h deleted file mode 100644 index ad31c670a6..0000000000 --- a/protocols/IcqOscarJ/src/oscar_filetransfer.h +++ /dev/null @@ -1,160 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// OSCAR File-Transfers headers -// ----------------------------------------------------------------------------- - -#ifndef __OSCAR_FILETRANSFER_H -#define __OSCAR_FILETRANSFER_H - -#define FT_MAGIC_ICQ 0x00 -#define FT_MAGIC_OSCAR 0x4F - -struct basic_filetransfer -{ - cookie_message_data pMessage; - BYTE ft_magic; - MCONTACT hContact; - int iCurrentFile; - DWORD dwCookie; -}; - -#define OFT_BUFFER_SIZE 8192 - -struct oft_file_record -{ - char *szContainer; - char *szFile; -}; - -char *FindFilePathContainer(const char **files, int iFile, char *szContainer); - - -// file-transfer status flags -#define OFTF_INITIALIZED 0x0001 // connection established (ack received) -#define OFTF_SENDING 0x0002 // sending files (receiving otherwise) -#define OFTF_FILE_REQUEST_SENT 0x0004 // request sent (sending only) -#define OFTF_FILE_REQUEST_RECEIVED 0x0008 // first request processed (receiving only) -#define OFTF_FILE_SENDING 0x0010 // sending file contents -#define OFTF_FILE_RECEIVING 0x0020 // receiving file contents -#define OFTF_FILE_DONE 0x0040 // file finished - -struct oscar_filetransfer : public basic_filetransfer -{ - int flags; // combination of OFTF_* - int containerCount; - char **file_containers; - oft_file_record *files; - char **files_list; // sending only - int currentIsDir; - int bUseProxy; - DWORD dwProxyIP; - DWORD dwRemoteInternalIP; - DWORD dwRemoteExternalIP; - WORD wRemotePort; - char *szSavePath; - char *szDescription; - char *szThisFile; - char *szThisPath; - // Request sequence - WORD wReqNum; - // OFT2 header data - WORD wEncrypt, wCompress; - WORD wFilesCount, wFilesLeft; - WORD wPartsCount, wPartsLeft; - DWORD64 qwTotalSize; - DWORD64 qwThisFileSize; - DWORD dwThisFileDate; // modification date - DWORD dwThisFileCheck; - DWORD dwRecvForkCheck, dwThisForkSize; - DWORD dwThisFileCreation; // creation date (not used) - DWORD dwThisForkCheck; - DWORD64 qwBytesDone; - DWORD dwRecvFileCheck; - char rawIDString[32]; - BYTE bHeaderFlags; - BYTE bNameOff, bSizeOff; - BYTE rawDummy[69]; - BYTE rawMacInfo[16]; - WORD wEncoding, wSubEncoding; - size_t cbRawFileName; - char *rawFileName; - // helper data - DWORD64 qwFileBytesDone; - int fileId; - struct oscar_connection *connection; - struct oscar_listener *listener; - DWORD dwLastNotify; - int resumeAction; -}; - -#define OFT_TYPE_REQUEST 0x0101 // I am going to send you this file, is that ok? -#define OFT_TYPE_READY 0x0202 // Yes, it is ok for you to send me that file -#define OFT_TYPE_DONE 0x0204 // I received that file with no problems -#define OFT_TYPE_RESUMEREQUEST 0x0205 // Resume transferring from position -#define OFT_TYPE_RESUMEREADY 0x0106 // Ok, I am ready to send it -#define OFT_TYPE_RESUMEACK 0x0207 // Fine, ready to receive - -struct oscar_connection -{ - MCONTACT hContact; - HNETLIBCONN hConnection; - int status; - DWORD dwUin; - uid_str szUid; - DWORD dwLocalInternalIP; - DWORD dwLocalExternalIP; - int type; - int incoming; - oscar_filetransfer *ft; - int wantIdleTime; -}; - -#define OCT_NORMAL 0 -#define OCT_REVERSE 1 -#define OCT_PROXY 2 -#define OCT_PROXY_INIT 3 -#define OCT_PROXY_RECV 4 -#define OCT_CLOSING 10 - -#define OCS_READY 0 -#define OCS_CONNECTED 1 -#define OCS_NEGOTIATION 2 -#define OCS_RESUME 3 -#define OCS_DATA 4 -#define OCS_PROXY 8 -#define OCS_WAITING 10 - -struct oscar_listener -{ - CIcqProto *ppro; - WORD wPort; - HNETLIBBIND hBoundPort; - oscar_filetransfer *ft; -}; - -#endif /* __OSCAR_FILETRANSFER_H */ - diff --git a/protocols/IcqOscarJ/src/resource.h b/protocols/IcqOscarJ/src/resource.h deleted file mode 100644 index 2c7145236b..0000000000 --- a/protocols/IcqOscarJ/src/resource.h +++ /dev/null @@ -1,168 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by D:\miranda-ng\protocols\IcqOscarJ\res\resources.rc -// -#define IDS_IDENTIFY 102 -#define IDD_ICQACCOUNT 103 -#define IDD_ASKAUTH 104 -#define IDD_LOGINPW 105 -#define IDD_OPT_ICQ 108 -#define IDD_OPT_ICQCONTACTS 109 -#define IDD_OPT_ICQFEATURES 110 -#define IDD_OPT_ICQPRIVACY 111 -#define IDD_INFO_ICQ 240 -#define IDD_ICQADVANCEDSEARCH 242 -#define IDD_ICQUPLOADLIST 253 -#define IDD_SETXSTATUS 256 -#define IDD_PWCONFIRM 300 -#define IDD_INFO_CHANGEINFO 301 -#define IDD_OPT_POPUPS 400 -#define IDC_POPUPS_ENABLED 410 -#define IDC_POPUPS_LOG_ENABLED 411 -#define IDC_POPUPS_SPAM_ENABLED 412 -#define IDC_POPUP_LOG0_TEXTCOLOR 420 -#define IDC_POPUP_LOG1_TEXTCOLOR 421 -#define IDC_POPUP_LOG2_TEXTCOLOR 422 -#define IDC_POPUP_LOG3_TEXTCOLOR 423 -#define IDC_POPUP_SPAM_TEXTCOLOR 425 -#define IDC_POPUP_LOG0_BACKCOLOR 430 -#define IDC_POPUP_LOG1_BACKCOLOR 431 -#define IDC_POPUP_LOG2_BACKCOLOR 432 -#define IDC_POPUP_LOG3_BACKCOLOR 433 -#define IDC_POPUP_SPAM_BACKCOLOR 435 -#define IDC_POPUP_LOG0_TIMEOUT 440 -#define IDC_POPUP_LOG1_TIMEOUT 441 -#define IDC_POPUP_LOG2_TIMEOUT 442 -#define IDC_POPUP_LOG3_TIMEOUT 443 -#define IDC_POPUP_SPAM_TIMEOUT 444 -#define IDC_USEWINCOLORS 450 -#define IDC_USESYSICONS 451 -#define IDC_PREVIEW 455 -#define IDC_LOG 1001 -#define IDI_EXPANDSTRINGEDIT 1001 -#define IDC_SAVEPASS 1004 -#define IDC_RETRXSTATUS 1005 -#define IDC_XTITLE_STATIC 1006 -#define IDC_XMSG_STATIC 1007 -#define IDC_SSL 1008 -#define IDC_MD5LOGIN 1009 -#define IDC_XTITLE 1010 -#define IDC_LEGACY 1010 -#define IDC_KEEPALIVE 1011 -#define IDC_XMSG 1011 -#define IDC_UTFSTATIC 1013 -#define IDC_UTFCODEPAGE 1014 -#define IDC_PW 1015 -#define IDC_TEMPVISIBLE 1015 -#define IDC_REGISTER 1016 -#define IDC_EDITAUTH 1017 -#define IDC_LOGINPW 1018 -#define IDC_INSTRUCTION 1019 -#define IDC_PASSWORD 1020 -#define IDC_SUPTIME 1020 -#define IDC_DCENABLE 1020 -#define IDC_DCPASSIVE 1021 -#define IDC_OLDPASS 1021 -#define IDC_ICQNUM 1022 -#define IDC_USEPOPUPCOLORS 1023 -#define IDC_USEDEFCOLORS 1024 -#define IDC_CLIST 1035 -#define IDC_XSTATUSENABLE 1040 -#define IDC_XSTATUSAUTO 1041 -#define IDC_XSTATUSRESET 1042 -#define IDC_MOODSENABLE 1043 -#define IDC_KILLSPAMBOTS 1045 -#define IDC_EMAIL 1048 -#define IDC_NICK 1053 -#define IDC_GENDER 1060 -#define IDC_CITY 1061 -#define IDC_STATE 1062 -#define IDC_COUNTRY 1063 -#define IDC_COMPANY 1066 -#define IDC_DEPARTMENT 1067 -#define IDC_POSITION 1069 -#define IDC_IP 1094 -#define IDC_UINSTATIC 1122 -#define IDC_UIN 1123 -#define IDC_STATIC11 1154 -#define IDC_STATIC12 1155 -#define IDC_ICQSERVER 1171 -#define IDC_ICQPORT 1172 -#define IDC_VERSION 1179 -#define IDC_FIRSTNAME 1224 -#define IDC_LASTNAME 1225 -#define IDC_REALIP 1230 -#define IDC_RECONNECTREQD 1239 -#define IDC_OFFLINETOENABLE 1240 -#define IDC_PORT 1249 -#define IDC_MIRVER 1251 -#define IDC_ONLINESINCE 1252 -#define IDC_SYSTEMUPTIME 1253 -#define IDC_IDLETIME 1254 -#define IDC_STATUS 1255 -#define IDC_SLOWSEND 1301 -#define IDC_LOGLEVEL 1331 -#define IDC_LEVELDESCR 1332 -#define IDC_NOERRMULTI 1333 -#define IDC_STICQGROUP 1374 -#define IDC_AGERANGE 1410 -#define IDC_MARITALSTATUS 1411 -#define IDC_KEYWORDS 1412 -#define IDC_LANGUAGE 1414 -#define IDC_WORKFIELD 1421 -#define IDC_PASTCAT 1422 -#define IDC_PASTKEY 1423 -#define IDC_INTERESTSCAT 1424 -#define IDC_INTERESTSKEY 1425 -#define IDC_ORGANISATION 1426 -#define IDC_ORGKEYWORDS 1427 -#define IDC_OTHERGROUP 1429 -#define IDC_ONLINEONLY 1430 -#define IDC_HOMEPAGECAT 1431 -#define IDC_HOMEPAGEKEY 1432 -#define IDC_SUMMARYGROUP 1434 -#define IDC_WORKGROUP 1435 -#define IDC_LOCATIONGROUP 1436 -#define IDC_BACKGROUNDGROUP 1437 -#define IDC_NEWUINLINK 1438 -#define IDC_LOOKUPLINK 1439 -#define IDC_RESETSERVER 1472 -#define IDC_UPLOADNOW 1521 -#define IDC_GROUPS 1522 -#define IDC_ALLGROUPS 1526 -#define IDC_VISIBILITY 1527 -#define IDC_IGNORE 1528 -#define IDC_ENABLE 1529 -#define IDC_LOADFROMSERVER 1530 -#define IDC_ADDSERVER 1532 -#define IDC_SAVETOSERVER 1533 -#define IDC_ENABLEAVATARS 1536 -#define IDC_AUTOLOADAVATARS 1537 -#define IDC_STRICTAVATARCHECK 1539 -#define IDC_WEBAWARE 1546 -#define IDC_DCALLOW_ANY 1547 -#define IDC_DCALLOW_CLIST 1548 -#define IDC_DCALLOW_AUTH 1549 -#define IDC_PUBLISHPRIMARY 1550 -#define IDC_ADD_ANY 1551 -#define IDC_ADD_AUTH 1552 -#define IDC_STATUSMSG_CLIST 1553 -#define IDC_STATUSMSG_VISIBLE 1554 -#define IDC_STATIC_NOTONLINE 1555 -#define IDC_STATIC_DC2 1556 -#define IDC_STATIC_DC1 1557 -#define IDC_STATIC_CLIST 1558 -#define IDC_SAVE 1600 -#define IDC_LIST 1601 -#define IDC_UPLOADING 1602 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 113 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1026 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/protocols/IcqOscarJ/src/stdafx.cxx b/protocols/IcqOscarJ/src/stdafx.cxx deleted file mode 100644 index 6ef3c8471b..0000000000 --- a/protocols/IcqOscarJ/src/stdafx.cxx +++ /dev/null @@ -1,18 +0,0 @@ -/* -Copyright (C) 2012-18 Miranda NG team (https://miranda-ng.org) - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation version 2 -of the License. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#include "stdafx.h" diff --git a/protocols/IcqOscarJ/src/stdafx.h b/protocols/IcqOscarJ/src/stdafx.h deleted file mode 100644 index 54f1712620..0000000000 --- a/protocols/IcqOscarJ/src/stdafx.h +++ /dev/null @@ -1,120 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// Includes all header files that should be precompiled to speed up compilation. -// ----------------------------------------------------------------------------- - -#pragma once - -// Windows includes -#include -#include - -// Standard includes -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef _DEBUG -#include -#endif - -#ifndef AW_VER_POSITIVE -#define AW_VER_POSITIVE 0x00000004 -#endif - -#ifndef _ASSERTE -#define _ASSERTE(x) -#endif - -// Miranda IM SDK includes -#include // This must be included first -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Project resources -#include "resource.h" - -// ICQ plugin includes -#include "version.h" -#include "globals.h" -#include "i18n.h" -#include "cookies.h" -#include "icq_packet.h" -#include "utilities.h" -#include "oscar_filetransfer.h" -#include "icq_direct.h" -#include "icq_server.h" -#include "icqosc_svcs.h" -#include "icq_servlist.h" -#include "icq_http.h" -#include "icq_fieldnames.h" -#include "icq_constants.h" -#include "capabilities.h" -#include "guids.h" -#include "stdpackets.h" -#include "tlv.h" -#include "channels.h" -#include "families.h" -#include "m_icq.h" -#include "icq_advsearch.h" -#include "log.h" - -#include "icq_rates.h" - -#include "icq_avatar.h" - -#include "changeinfo.h" -#include "icq_popups.h" -#include "icq_proto.h" - -extern IconItem iconList[]; \ No newline at end of file diff --git a/protocols/IcqOscarJ/src/stdpackets.cpp b/protocols/IcqOscarJ/src/stdpackets.cpp deleted file mode 100644 index 0888bd524d..0000000000 --- a/protocols/IcqOscarJ/src/stdpackets.cpp +++ /dev/null @@ -1,1798 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -extern const int moodXStatus[]; - -/***************************************************************************** -* -* Some handy extra pack functions for basic message type headers -* -*/ - -// This is the part of the message header that is common for all message channels -static void packServMsgSendHeader(icq_packet *p, DWORD dwSequence, DWORD dwID1, DWORD dwID2, DWORD dwUin, const char *szUID, WORD wFmt, size_t wLen) -{ - serverPacketInit(p, 21 + getUIDLen(dwUin, szUID) + wLen); - packFNACHeader(p, ICQ_MSG_FAMILY, ICQ_MSG_SRV_SEND, 0, dwSequence | ICQ_MSG_SRV_SEND << 0x10); - packLEDWord(p, dwID1); // Msg ID part 1 - packLEDWord(p, dwID2); // Msg ID part 2 - packWord(p, wFmt); // Message channel - packUID(p, dwUin, szUID); // User ID -} - -static void packServIcqExtensionHeader(icq_packet *p, CIcqProto *ppro, size_t wLen, WORD wType, WORD wSeq, WORD wCmd = ICQ_META_CLI_REQUEST) -{ - serverPacketInit(p, 24 + wLen); - packFNACHeader(p, ICQ_EXTENSIONS_FAMILY, ICQ_META_CLI_REQUEST, 0, wSeq | (wCmd << 0x10)); - packWord(p, 0x01); // TLV type 1 - packWord(p, WORD(10 + wLen)); // TLV len - packLEWord(p, WORD(8 + wLen)); // Data chunk size (TLV.Length-2) - packLEDWord(p, ppro->m_dwLocalUIN); // My UIN - packLEWord(p, wType); // Request type - packWord(p, wSeq); -} - -static void packServIcqDirectoryHeader(icq_packet *p, CIcqProto *ppro, size_t wLen, WORD wType, WORD wCommand, WORD wSeq, WORD wSubCommand = ICQ_META_CLI_REQUEST) -{ - packServIcqExtensionHeader(p, ppro, wLen + 0x1E, CLI_META_INFO_REQ, wSeq, wSubCommand); - packLEWord(p, wType); - packLEWord(p, WORD(wLen + 0x1A)); - packFNACHeader(p, 0x5b9, wCommand, 0, 0, 2); - packWord(p, 0); - packWord(p, (WORD)GetACP()); - packDWord(p, 2); -} - -static void packServTLV5HeaderBasic(icq_packet *p, size_t wLen, DWORD ID1, DWORD ID2, WORD wCommand, const plugin_guid pGuid) -{ - // TLV(5) header - packWord(p, 0x05); // Type - packWord(p, WORD(26 + wLen)); // Len - // TLV(5) data - packWord(p, wCommand); // Command - packLEDWord(p, ID1); // msgid1 - packLEDWord(p, ID2); // msgid2 - packGUID(p, pGuid); // capabilities (4 dwords) -} - -static void packServTLV5HeaderMsg(icq_packet *p, size_t wLen, DWORD ID1, DWORD ID2, WORD wAckType) -{ - packServTLV5HeaderBasic(p, wLen + 10, ID1, ID2, 0, MCAP_SRV_RELAY_FMT); - - packTLVWord(p, 0x0A, wAckType); // TLV: 0x0A Acktype: 1 for normal, 2 for ack - packDWord(p, 0x000F0000); // TLV: 0x0F empty -} - -static void packServTLV2711Header(icq_packet *packet, WORD wCookie, WORD wVersion, BYTE bMsgType, BYTE bMsgFlags, WORD X1, WORD X2, size_t nLen) -{ - packWord(packet, 0x2711); // Type - packWord(packet, WORD(51 + nLen)); // Len - // TLV(0x2711) data - packLEWord(packet, 0x1B); // Unknown - packByte(packet, (BYTE)wVersion); // Client (message) version - packGUID(packet, PSIG_MESSAGE); - packDWord(packet, CLIENTFEATURES); - packDWord(packet, DC_TYPE); - packLEWord(packet, wCookie); // Reference cookie - packLEWord(packet, 0x0E); // Unknown - packLEWord(packet, wCookie); // Reference cookie again - packDWord(packet, 0); // Unknown (12 bytes) - packDWord(packet, 0); // - - packDWord(packet, 0); // - - packByte(packet, bMsgType); // Message type - packByte(packet, bMsgFlags); // Flags - packLEWord(packet, X1); // Accepted - packWord(packet, X2); // Unknown, priority? -} - -static void packServDCInfo(icq_packet *p, CIcqProto* ppro, BOOL bEmpty) -{ - packTLVDWord(p, 0x03, bEmpty ? 0 : ppro->getDword("RealIP", 0)); // TLV: 0x03 DWORD IP - packTLVWord(p, 0x05, WORD(bEmpty ? 0 : ppro->wListenPort)); // TLV: 0x05 Listen port -} - -static void packServChannel2Header(icq_packet *p, CIcqProto* ppro, DWORD dwUin, size_t wLen, DWORD dwID1, DWORD dwID2, DWORD dwCookie, WORD wVersion, BYTE bMsgType, BYTE bMsgFlags, WORD wPriority, int isAck, int includeDcInfo, BYTE bRequestServerAck) -{ - packServMsgSendHeader(p, dwCookie, dwID1, dwID2, dwUin, nullptr, 0x0002, wLen + 95 + (bRequestServerAck ? 4 : 0) + (includeDcInfo ? 14 : 0)); - - packWord(p, 0x05); // TLV type - packWord(p, WORD(wLen + 91 + (includeDcInfo ? 14 : 0))); /* TLV len */ - packWord(p, WORD(isAck ? 2 : 0)); /* not aborting anything */ - packLEDWord(p, dwID1); // Msg ID part 1 - packLEDWord(p, dwID2); // Msg ID part 2 - packGUID(p, MCAP_SRV_RELAY_FMT); /* capability (4 dwords) */ - packDWord(p, 0x000A0002); // TLV: 0x0A WORD: 1 for normal, 2 for ack - packWord(p, isAck ? 2 : 1); - - if (includeDcInfo) - packServDCInfo(p, ppro, FALSE); - - packDWord(p, 0x000F0000); // TLV: 0x0F empty - - packServTLV2711Header(p, (WORD)dwCookie, wVersion, bMsgType, bMsgFlags, (WORD)MirandaStatusToIcq(ppro->m_iStatus), wPriority, wLen); -} - -static void packServAdvancedReply(icq_packet *p, DWORD dwUin, const char *szUid, DWORD dwID1, DWORD dwID2, WORD wCookie, size_t wLen) -{ - serverPacketInit(p, getUIDLen(dwUin, szUid) + 23 + wLen); - packFNACHeader(p, ICQ_MSG_FAMILY, ICQ_MSG_RESPONSE, 0, ICQ_MSG_RESPONSE << 0x10 | (wCookie & 0x7FFF)); - packLEDWord(p, dwID1); // Msg ID part 1 - packLEDWord(p, dwID2); // Msg ID part 2 - packWord(p, 0x02); // Channel - packUID(p, dwUin, szUid); // Contact UID - packWord(p, 0x03); // Msg specific formating -} - -static void packServAdvancedMsgReply(icq_packet *p, DWORD dwUin, const char *szUid, DWORD dwID1, DWORD dwID2, WORD wCookie, WORD wVersion, BYTE bMsgType, BYTE bMsgFlags, size_t wLen) -{ - packServAdvancedReply(p, dwUin, szUid, dwID1, dwID2, wCookie, wLen + 51); - - packLEWord(p, 0x1B); // Unknown - packByte(p, (BYTE)wVersion); // Protocol version - packGUID(p, PSIG_MESSAGE); - packDWord(p, CLIENTFEATURES); - packDWord(p, DC_TYPE); - packLEWord(p, wCookie); // Reference - packLEWord(p, 0x0E); // Unknown - packLEWord(p, wCookie); // Reference - packDWord(p, 0); // Unknown - packDWord(p, 0); // Unknown - packDWord(p, 0); // Unknown - packByte(p, bMsgType); // Message type - packByte(p, bMsgFlags); // Message flags - packLEWord(p, 0); // Ack status code ( 0 = accepted, this is hardcoded because - // it is only used this way yet) - packLEWord(p, 0); // Unused priority field -} - -void packMsgColorInfo(icq_packet *packet) -{ // TODO: make configurable - packLEDWord(packet, 0x00000000); // Foreground colour - packLEDWord(packet, 0x00FFFFFF); // Background colour -} - -void packEmptyMsg(icq_packet *packet) -{ - packLEWord(packet, 1); - packByte(packet, 0); -} - -/***************************************************************************** -* -* Functions to actually send the stuff -* -*/ - -void CIcqProto::icq_sendCloseConnection() -{ - icq_packet packet; - - packet.wLen = 0; - write_flap(&packet, ICQ_CLOSE_CHAN); - sendServPacket(&packet); -} - -void CIcqProto::icq_requestnewfamily(WORD wFamily, void (CIcqProto::*familyhandler)(HNETLIBCONN hConn, char* cookie, size_t cookieLen)) -{ - int bRequestSSL = m_bSecureConnection && (wFamily != ICQ_AVATAR_FAMILY); // Avatar servers does not support SSL - - cookie_family_request *request = (cookie_family_request*)SAFE_MALLOC(sizeof(cookie_family_request)); - request->wFamily = wFamily; - request->familyHandler = familyhandler; - - DWORD dwCookie = AllocateCookie(CKT_SERVICEREQUEST, ICQ_CLIENT_NEW_SERVICE, 0, request); // generate and alloc cookie - - icq_packet packet; - serverPacketInit(&packet, 12 + (bRequestSSL ? 4 : 0)); - packFNACHeader(&packet, ICQ_SERVICE_FAMILY, ICQ_CLIENT_NEW_SERVICE, 0, dwCookie); - packWord(&packet, wFamily); - if (bRequestSSL) - packDWord(&packet, 0x008C0000); // use SSL - - sendServPacket(&packet); -} - -void CIcqProto::icq_setidle(bool bIsIdle) -{ - // if mode isn't changed, don't spam the server - if (bIsIdle == m_bIdleMode) { - debugLogA("ICQ: idle mode wasn't changed (%d)", bIsIdle); - return; - } - - /* SNAC 1,11 */ - debugLogA("ICQ: set idle %d", bIsIdle); - icq_packet packet; - serverPacketInit(&packet, 14); - packFNACHeader(&packet, ICQ_SERVICE_FAMILY, ICQ_CLIENT_SET_IDLE); - if (bIsIdle) - packDWord(&packet, 0x0000003C); - else - packDWord(&packet, 0x00000000); - - m_bIdleMode = bIsIdle; - sendServPacket(&packet); -} - -void CIcqProto::icq_setstatus(WORD wStatus, const char *szStatusNote) -{ - char *szCurrentStatusNote = szStatusNote ? getSettingStringUtf(NULL, DBSETTING_STATUS_NOTE, nullptr) : nullptr; - size_t wStatusMoodLen = 0, wStatusNoteLen = 0, wSessionDataLen = 0; - char *szMoodData = nullptr; - - if (szStatusNote && mir_strcmp(szCurrentStatusNote, szStatusNote)) { // status note was changed, update now - DBVARIANT dbv = { DBVT_DELETED }; - if (m_bMoodsEnabled && !getString(DBSETTING_STATUS_MOOD, &dbv)) - szMoodData = null_strdup(dbv.pszVal); - - db_free(&dbv); - - wStatusNoteLen = mir_strlen(szStatusNote); - wStatusMoodLen = mir_strlen(szMoodData); - - wSessionDataLen = (wStatusNoteLen ? wStatusNoteLen + 4 : 0) + 4 + wStatusMoodLen + 4; - } - SAFE_FREE(&szCurrentStatusNote); - - // Pack data in packet - icq_packet packet; - serverPacketInit(&packet, 18 + (wSessionDataLen ? wSessionDataLen + 4 : 0)); - packFNACHeader(&packet, ICQ_SERVICE_FAMILY, ICQ_CLIENT_SET_STATUS); - packWord(&packet, 0x06); // TLV 6 - packWord(&packet, 0x04); // TLV length - packWord(&packet, GetMyStatusFlags()); // Status flags - packWord(&packet, wStatus); // Status - if (wSessionDataLen) { - packWord(&packet, 0x1D); // TLV 1D - packWord(&packet, WORD(wSessionDataLen)); // TLV length - packWord(&packet, 0x02); // Item Type - if (wStatusNoteLen) { - packWord(&packet, 0x400 | (WORD)(wStatusNoteLen + 4)); // Flags + Item Length - packWord(&packet, WORD(wStatusNoteLen)); // Text Length - packBuffer(&packet, (LPBYTE)szStatusNote, wStatusNoteLen); - packWord(&packet, 0); // Encoding not specified (utf-8 is default) - } - else packWord(&packet, 0); // Flags + Item Length - - packWord(&packet, 0x0E); // Item Type - packWord(&packet, WORD(wStatusMoodLen)); // Flags + Item Length - if (wStatusMoodLen) - packBuffer(&packet, (LPBYTE)szMoodData, wStatusMoodLen); // Mood - - // Save current status note - db_set_utf(NULL, m_szModuleName, DBSETTING_STATUS_NOTE, szStatusNote); - } - // Release memory - SAFE_FREE(&szMoodData); - - // Send packet - sendServPacket(&packet); -} - -DWORD CIcqProto::icq_SendChannel1Message(DWORD dwUin, char *szUID, MCONTACT hContact, char *pszText, cookie_message_data *pCookieData) -{ - size_t wMessageLen = mir_strlen(pszText); - DWORD dwCookie = AllocateCookie(CKT_MESSAGE, 0, hContact, (void*)pCookieData); - size_t wPacketLength = (pCookieData->nAckType == ACKTYPE_SERVER) ? 25 : 21; - - // Pack the standard header - icq_packet packet; - packServMsgSendHeader(&packet, dwCookie, pCookieData->dwMsgID1, pCookieData->dwMsgID2, dwUin, szUID, 1, wPacketLength + wMessageLen); - - // Pack first TLV - packWord(&packet, 0x0002); // TLV(2) - packWord(&packet, WORD(wMessageLen + 13)); // TLV len - - // Pack client features - packWord(&packet, 0x0501); // TLV(501) - packWord(&packet, 0x0001); // TLV len - packByte(&packet, 0x1); // Features, meaning unknown, duplicated from ICQ Lite - - // Pack text TLV - packWord(&packet, 0x0101); // TLV(2) - packWord(&packet, WORD(wMessageLen + 4)); // TLV len - packWord(&packet, 0x0003); // Message charset number, again copied from ICQ Lite - packWord(&packet, 0x0000); // Message charset subset - packBuffer(&packet, (LPBYTE)pszText, wMessageLen); // Message text - - // Pack request server ack TLV - if (pCookieData->nAckType == ACKTYPE_SERVER) - packDWord(&packet, 0x00030000); // TLV(3) - - // Pack store on server TLV - packDWord(&packet, 0x00060000); // TLV(6) - - sendServPacket(&packet); - - return dwCookie; -} - - -DWORD CIcqProto::icq_SendChannel1MessageW(DWORD dwUin, char *szUID, MCONTACT hContact, WCHAR *pszText, cookie_message_data *pCookieData) -{ - WORD wMessageLen = WORD(mir_wstrlen(pszText) * sizeof(WCHAR)); - DWORD dwCookie = AllocateCookie(CKT_MESSAGE, 0, hContact, (void*)pCookieData); - - WORD wPacketLength = (pCookieData->nAckType == ACKTYPE_SERVER) ? 26 : 22; - - // Pack the standard header - icq_packet packet; - packServMsgSendHeader(&packet, dwCookie, pCookieData->dwMsgID1, pCookieData->dwMsgID2, dwUin, szUID, 1, wPacketLength + wMessageLen); - - // Pack first TLV - packWord(&packet, 0x0002); // TLV(2) - packWord(&packet, WORD(wMessageLen + 14)); // TLV len - - // Pack client features - packWord(&packet, 0x0501); // TLV(501) - packWord(&packet, 0x0002); // TLV len - packWord(&packet, 0x0106); // Features, meaning unknown, duplicated from ICQ 2003b - - // Pack text TLV - packWord(&packet, 0x0101); // TLV(2) - packWord(&packet, WORD(wMessageLen + 4)); // TLV len - packWord(&packet, 0x0002); // Message charset number, again copied from ICQ 2003b - packWord(&packet, 0x0000); // Message charset subset - WCHAR *ppText = pszText; // we must convert the widestring - for (int i = 0; i < wMessageLen; i += 2, ppText++) - packWord(&packet, *ppText); - - // Pack request server ack TLV - if (pCookieData->nAckType == ACKTYPE_SERVER) - packDWord(&packet, 0x00030000); // TLV(3) - - // Pack store on server TLV - packDWord(&packet, 0x00060000); // TLV(6) - - sendServPacket(&packet); - return dwCookie; -} - -DWORD CIcqProto::icq_SendChannel2Message(DWORD dwUin, MCONTACT hContact, const char *szMessage, size_t nBodyLen, WORD wPriority, cookie_message_data *pCookieData, char *szCap) -{ - DWORD dwCookie = AllocateCookie(CKT_MESSAGE, 0, hContact, (void*)pCookieData); - - // Pack the standard header - icq_packet packet; - packServChannel2Header(&packet, this, dwUin, nBodyLen + (szCap ? 53 : 11), pCookieData->dwMsgID1, pCookieData->dwMsgID2, dwCookie, ICQ_VERSION, (BYTE)pCookieData->bMessageType, 0, - wPriority, 0, 0, (BYTE)((pCookieData->nAckType == ACKTYPE_SERVER) ? 1 : 0)); - - packLEWord(&packet, WORD(nBodyLen + 1)); // Length of message - packBuffer(&packet, (LPBYTE)szMessage, nBodyLen + 1); // Message - packMsgColorInfo(&packet); - - if (szCap) { - packLEDWord(&packet, 0x00000026); // length of GUID - packBuffer(&packet, (LPBYTE)szCap, 0x26); // UTF-8 GUID - } - - // Pack request server ack TLV - if (pCookieData->nAckType == ACKTYPE_SERVER) - packDWord(&packet, 0x00030000); // TLV(3) - - sendServPacket(&packet); - return dwCookie; -} - -DWORD CIcqProto::icq_SendChannel2Contacts(DWORD dwUin, char *szUid, MCONTACT hContact, const char *pData, size_t wDataLen, const char *pNames, size_t wNamesLen, cookie_message_data *pCookieData) -{ - DWORD dwCookie = AllocateCookie(CKT_MESSAGE, 0, hContact, pCookieData); - - size_t wPacketLength = wDataLen + wNamesLen + 0x12; - - // Pack the standard header - icq_packet packet; - packServMsgSendHeader(&packet, dwCookie, pCookieData->dwMsgID1, pCookieData->dwMsgID2, dwUin, szUid, 2, wPacketLength + ((pCookieData->nAckType == ACKTYPE_SERVER) ? 0x22 : 0x1E)); - - packServTLV5HeaderBasic(&packet, wPacketLength, pCookieData->dwMsgID1, pCookieData->dwMsgID2, 0, MCAP_CONTACTS); - - packTLVWord(&packet, 0x0A, 1); // TLV: 0x0A Acktype: 1 for normal, 2 for ack - packDWord(&packet, 0x000F0000); // TLV: 0x0F empty - packTLV(&packet, 0x2711, wDataLen, (LPBYTE)pData); // TLV: 0x2711 Content (Contact UIDs) - packTLV(&packet, 0x2712, wNamesLen, (LPBYTE)pNames);// TLV: 0x2712 Extended Content (Contact NickNames) - - // Pack request ack TLV - if (pCookieData->nAckType == ACKTYPE_SERVER) { - packDWord(&packet, 0x00030000); // TLV(3) - } - - sendServPacket(&packet); - return dwCookie; -} - -DWORD CIcqProto::icq_SendChannel4Message(DWORD dwUin, MCONTACT hContact, BYTE bMsgType, size_t wMsgLen, const char *szMsg, cookie_message_data *pCookieData) -{ - DWORD dwCookie = AllocateCookie(CKT_MESSAGE, 0, hContact, (void*)pCookieData); - size_t wPacketLength = (pCookieData->nAckType == ACKTYPE_SERVER) ? 28 : 24; - - // Pack the standard header - icq_packet packet; - packServMsgSendHeader(&packet, dwCookie, pCookieData->dwMsgID1, pCookieData->dwMsgID2, dwUin, nullptr, 4, wPacketLength + wMsgLen); - - // Pack first TLV - packWord(&packet, 0x05); // TLV(5) - packWord(&packet, WORD(wMsgLen + 16)); // TLV len - packLEDWord(&packet, m_dwLocalUIN); // My UIN - packByte(&packet, bMsgType); // Message type - packByte(&packet, 0); // Message flags - packLEWord(&packet, WORD(wMsgLen)); // Message length - packBuffer(&packet, (LPBYTE)szMsg, wMsgLen); // Message text - packMsgColorInfo(&packet); - - // Pack request ack TLV - if (pCookieData->nAckType == ACKTYPE_SERVER) - packDWord(&packet, 0x00030000); // TLV(3) - - // Pack store on server TLV - packDWord(&packet, 0x00060000); // TLV(6) - - sendServPacket(&packet); - - return dwCookie; -} - - -void CIcqProto::sendOwnerInfoRequest(void) -{ - icq_packet packet; - - if (m_bLegacyFix) { - cookie_fam15_data *pCookieData = (cookie_fam15_data*)SAFE_MALLOC(sizeof(cookie_fam15_data)); - pCookieData->bRequestType = REQUESTTYPE_OWNER; - DWORD dwCookie = AllocateCookie(CKT_FAMILYSPECIAL, 0, NULL, (void*)pCookieData); - - packServIcqExtensionHeader(&packet, this, 6, 0x07D0, (WORD)dwCookie); - packLEWord(&packet, META_REQUEST_SELF_INFO); - packLEDWord(&packet, m_dwLocalUIN); - } - else { - cookie_directory_data *pCookieData = (cookie_directory_data*)SAFE_MALLOC(sizeof(cookie_directory_data)); - pCookieData->bRequestType = DIRECTORYREQUEST_INFOOWNER; - - DWORD dwCookie = AllocateCookie(CKT_DIRECTORY_QUERY, 0, NULL, (void*)pCookieData); - WORD wDataLen = getUINLen(m_dwLocalUIN) + 4; - - packServIcqDirectoryHeader(&packet, this, wDataLen + 8, META_DIRECTORY_QUERY, DIRECTORY_QUERY_INFO, (WORD)dwCookie); - packWord(&packet, 0x03); // with interests (ICQ6 uses 2 at login) - packDWord(&packet, 0x01); - packWord(&packet, wDataLen); - - packTLVUID(&packet, 0x32, m_dwLocalUIN, nullptr); - } - - sendServPacket(&packet); -} - -DWORD CIcqProto::sendUserInfoMultiRequest(BYTE *pRequestData, size_t dataLen, int nItems) -{ - cookie_directory_data *pCookieData = (cookie_directory_data*)SAFE_MALLOC(sizeof(cookie_directory_data)); - if (!pCookieData) - return 0; // Failure - - pCookieData->bRequestType = DIRECTORYREQUEST_INFOMULTI; - DWORD dwCookie = AllocateCookie(CKT_DIRECTORY_QUERY, 0, NULL, (void*)pCookieData); - - icq_packet packet; - packServIcqDirectoryHeader(&packet, this, dataLen + 2, META_DIRECTORY_QUERY, DIRECTORY_QUERY_MULTI_INFO, (WORD)dwCookie); - packWord(&packet, nItems); - packBuffer(&packet, pRequestData, dataLen); - - sendServPacket(&packet); - - return dwCookie; -} - -DWORD CIcqProto::icq_sendGetInfoServ(MCONTACT hContact, DWORD dwUin, int bManual) -{ - if (IsServerOverRate(ICQ_EXTENSIONS_FAMILY, ICQ_META_CLI_REQUEST, bManual ? RML_IDLE_10 : RML_IDLE_50)) - return 0; - - DBVARIANT infoToken = { DBVT_DELETED }; - BYTE *pToken = nullptr; - WORD cbToken = 0; - - if (!getSetting(hContact, DBSETTING_METAINFO_TOKEN, &infoToken)) { // retrieve user details using privacy token - cbToken = infoToken.cpbVal; - pToken = (BYTE*)_alloca(cbToken); - memcpy(pToken, infoToken.pbVal, cbToken); - - db_free(&infoToken); - } - - cookie_directory_data *pCookieData = (cookie_directory_data*)SAFE_MALLOC(sizeof(cookie_directory_data)); - - icq_packet packet; - if (m_bLegacyFix) { - pCookieData->bRequestType = REQUESTTYPE_USERDETAILED; - - DWORD dwCookie = AllocateCookie(CKT_FAMILYSPECIAL, 0, hContact, (void*)pCookieData); - - packServIcqExtensionHeader(&packet, this, 6, CLI_META_INFO_REQ, (WORD)dwCookie); - packLEWord(&packet, META_REQUEST_FULL_INFO); - packLEDWord(&packet, dwUin); - - sendServPacket(&packet); - return dwCookie; - } - - pCookieData->bRequestType = DIRECTORYREQUEST_INFOUSER; - - DWORD dwCookie = AllocateCookie(CKT_DIRECTORY_QUERY, 0, hContact, (void*)pCookieData); - WORD wDataLen = cbToken + getUINLen(dwUin) + (cbToken ? 8 : 4); - - packServIcqDirectoryHeader(&packet, this, wDataLen + 8, META_DIRECTORY_QUERY, DIRECTORY_QUERY_INFO, (WORD)dwCookie); - packWord(&packet, 0x03); - packDWord(&packet, 1); - packWord(&packet, wDataLen); - if (pToken) - packTLV(&packet, 0x3C, cbToken, pToken); - packTLVUID(&packet, 0x32, dwUin, nullptr); - - sendServPacket(&packet); - - return dwCookie; -} - - -DWORD CIcqProto::icq_sendGetAimProfileServ(MCONTACT hContact, char* szUid) -{ - if (IsServerOverRate(ICQ_LOCATION_FAMILY, ICQ_LOCATION_REQ_USER_INFO, RML_IDLE_10)) - return 0; - - cookie_fam15_data *pCookieData = (cookie_fam15_data*)SAFE_MALLOC(sizeof(cookie_fam15_data)); - pCookieData->bRequestType = REQUESTTYPE_PROFILE; - - DWORD dwCookie = AllocateCookie(CKT_FAMILYSPECIAL, ICQ_LOCATION_REQ_USER_INFO, hContact, (void*)pCookieData); - BYTE bUIDlen = (BYTE)mir_strlen(szUid); - - icq_packet packet; - serverPacketInit(&packet, 13 + bUIDlen); - packFNACHeader(&packet, ICQ_LOCATION_FAMILY, ICQ_LOCATION_REQ_USER_INFO, 0, dwCookie); - packWord(&packet, 0x01); // request profile info - packByte(&packet, bUIDlen); - packBuffer(&packet, (LPBYTE)szUid, bUIDlen); - - sendServPacket(&packet); - - return dwCookie; -} - - -DWORD CIcqProto::icq_sendGetAwayMsgServ(MCONTACT hContact, DWORD dwUin, int type, WORD wVersion) -{ - if (IsServerOverRate(ICQ_MSG_FAMILY, ICQ_MSG_SRV_SEND, RML_IDLE_30)) - return 0; - - cookie_message_data *pCookieData = CreateMessageCookie(MTYPE_AUTOAWAY, (BYTE)type); - DWORD dwCookie = AllocateCookie(CKT_MESSAGE, 0, hContact, (void*)pCookieData); - - icq_packet packet; - packServChannel2Header(&packet, this, dwUin, 3, pCookieData->dwMsgID1, pCookieData->dwMsgID2, dwCookie, wVersion, (BYTE)type, 3, 1, 0, 0, 0); - packEmptyMsg(&packet); // Message - sendServPacket(&packet); - - return dwCookie; -} - - -DWORD CIcqProto::icq_sendGetAwayMsgServExt(MCONTACT hContact, DWORD dwUin, char *szUID, int type, WORD wVersion) -{ - if (IsServerOverRate(ICQ_MSG_FAMILY, ICQ_MSG_SRV_SEND, RML_IDLE_30)) - return 0; - - cookie_message_data *pCookieData = CreateMessageCookie(MTYPE_AUTOAWAY, (BYTE)type); - DWORD dwCookie = AllocateCookie(CKT_MESSAGE, 0, hContact, (void*)pCookieData); - - icq_packet packet; - packServMsgSendHeader(&packet, dwCookie, pCookieData->dwMsgID1, pCookieData->dwMsgID2, dwUin, szUID, 2, 122 + getPluginTypeIdLen(type)); - - // TLV(5) header - packServTLV5HeaderMsg(&packet, 82 + getPluginTypeIdLen(type), pCookieData->dwMsgID1, pCookieData->dwMsgID2, 1); - - // TLV(0x2711) header - packServTLV2711Header(&packet, (WORD)dwCookie, wVersion, MTYPE_PLUGIN, 0, 0, 0x100, 27 + getPluginTypeIdLen(type)); - - packLEWord(&packet, 0); // Empty msg - - packPluginTypeId(&packet, type); - - packLEDWord(&packet, 0x15); - packLEDWord(&packet, 0); - packLEDWord(&packet, 0x0D); - packBuffer(&packet, (LPBYTE)"text/x-aolrtf", 0x0D); - - // Send the monster - sendServPacket(&packet); - - return dwCookie; -} - - -DWORD CIcqProto::icq_sendGetAimAwayMsgServ(MCONTACT hContact, char *szUID, int type) -{ - BYTE bUIDlen = (BYTE)mir_strlen(szUID); - - cookie_message_data *pCookieData = CreateMessageCookie(MTYPE_AUTOAWAY, (byte)type); - DWORD dwCookie = AllocateCookie(CKT_MESSAGE, 0, hContact, (void*)pCookieData); - - icq_packet packet; - serverPacketInit(&packet, 13 + bUIDlen); - packFNACHeader(&packet, ICQ_LOCATION_FAMILY, ICQ_LOCATION_REQ_USER_INFO, 0, dwCookie); - packWord(&packet, 0x03); - packUID(&packet, 0, szUID); - - sendServPacket(&packet); - - return dwCookie; -} - - -void CIcqProto::icq_sendSetAimAwayMsgServ(const char *szMsg) -{ - icq_packet packet; - size_t wMsgLen = mir_strlen(szMsg); - - DWORD dwCookie = GenerateCookie(ICQ_LOCATION_SET_USER_INFO); - - if (wMsgLen) { - if (wMsgLen > 0x1000) wMsgLen = 0x1000; // limit length - - if (IsUSASCII(szMsg, wMsgLen)) { - const char* fmt = "text/x-aolrtf; charset=\"us-ascii\""; - size_t fmtlen = mir_strlen(fmt); - - serverPacketInit(&packet, 23 + wMsgLen + fmtlen); - packFNACHeader(&packet, ICQ_LOCATION_FAMILY, ICQ_LOCATION_SET_USER_INFO, 0, dwCookie); - packTLV(&packet, 0x0f, 1, (LPBYTE)"\x02"); - packTLV(&packet, 0x03, fmtlen, (LPBYTE)fmt); - packTLV(&packet, 0x04, wMsgLen, (LPBYTE)szMsg); - } - else { - const char* fmt = "text/x-aolrtf; charset=\"unicode-2-0\""; - size_t fmtlen = mir_strlen(fmt); - - WCHAR *szMsgW = make_unicode_string(szMsg); - wMsgLen = mir_wstrlen(szMsgW) * sizeof(WCHAR); - - WCHAR *szMsgW2 = (WCHAR*)alloca(wMsgLen), *szMsgW3 = szMsgW; - unpackWideString((BYTE**)&szMsgW3, szMsgW2, wMsgLen); - SAFE_FREE(&szMsgW); - - serverPacketInit(&packet, 23 + wMsgLen + fmtlen); - packFNACHeader(&packet, ICQ_LOCATION_FAMILY, ICQ_LOCATION_SET_USER_INFO, 0, dwCookie); - packTLV(&packet, 0x0f, 1, (LPBYTE)"\x02"); - packTLV(&packet, 0x03, fmtlen, (LPBYTE)fmt); - packTLV(&packet, 0x04, wMsgLen, (LPBYTE)szMsgW2); - } - } - else { - serverPacketInit(&packet, 19); - packFNACHeader(&packet, ICQ_LOCATION_FAMILY, ICQ_LOCATION_SET_USER_INFO, 0, dwCookie); - packTLV(&packet, 0x0f, 1, (LPBYTE)"\x02"); - packTLV(&packet, 0x04, 0, nullptr); - } - - sendServPacket(&packet); -} - -void CIcqProto::icq_sendFileSendServv7(filetransfer* ft, const char *szFiles) -{ - char *szFilesAnsi = nullptr, *szDescrAnsi = nullptr; - - if (!utf8_decode(szFiles, &szFilesAnsi)) - szFilesAnsi = _strdup(szFiles); // Legacy fix - - if (!utf8_decode(ft->szDescription, &szDescrAnsi)) - szDescrAnsi = _strdup(ft->szDescription); // Legacy fix - - size_t wFilesLen = mir_strlen(szFilesAnsi); - size_t wDescrLen = mir_strlen(szDescrAnsi); - - icq_packet packet; - packServChannel2Header(&packet, this, ft->dwUin, 18 + wDescrLen + wFilesLen, ft->pMessage.dwMsgID1, ft->pMessage.dwMsgID2, ft->dwCookie, ICQ_VERSION, MTYPE_FILEREQ, 0, 1, 0, 1, 1); - - packLEWord(&packet, WORD(wDescrLen + 1)); - packBuffer(&packet, (LPBYTE)szDescrAnsi, wDescrLen + 1); - packLEDWord(&packet, 0); // unknown - packLEWord(&packet, WORD(wFilesLen + 1)); - packBuffer(&packet, (LPBYTE)szFilesAnsi, wFilesLen + 1); - packLEDWord(&packet, ft->dwTotalSize); - packLEDWord(&packet, 0); // unknown - - SAFE_FREE(&szFilesAnsi); - SAFE_FREE(&szDescrAnsi); - - sendServPacket(&packet); -} - -void CIcqProto::icq_sendFileSendServv8(filetransfer* ft, const char *szFiles, int nAckType) -{ - icq_packet packet; - char *szFilesAnsi = nullptr, *szDescrAnsi = nullptr; - - if (!utf8_decode(szFiles, &szFilesAnsi)) - szFilesAnsi = _strdup(szFiles); // Legacy fix - - if (!utf8_decode(ft->szDescription, &szDescrAnsi)) - szDescrAnsi = _strdup(ft->szDescription); // Legacy fix - - size_t wFilesLen = mir_strlen(szFilesAnsi); - size_t wDescrLen = mir_strlen(szDescrAnsi); - - // 202 + UIN len + file description (no null) + file name (null included) - // Packet size = Flap length + 4 - size_t wFlapLen = 178 + wDescrLen + wFilesLen + (nAckType == ACKTYPE_SERVER ? 4 : 0); - packServMsgSendHeader(&packet, ft->dwCookie, ft->pMessage.dwMsgID1, ft->pMessage.dwMsgID2, ft->dwUin, nullptr, 2, wFlapLen); - - // TLV(5) header - packServTLV5HeaderMsg(&packet, 138 + wDescrLen + wFilesLen, ft->pMessage.dwMsgID1, ft->pMessage.dwMsgID2, 1); - - // Port & IP information - packServDCInfo(&packet, this, FALSE); - - // TLV(0x2711) header - packServTLV2711Header(&packet, (WORD)ft->dwCookie, ICQ_VERSION, MTYPE_PLUGIN, 0, MirandaStatusToIcq(m_iStatus), 0x100, 69 + wDescrLen + wFilesLen); - - packEmptyMsg(&packet); // Message (unused) - - packPluginTypeId(&packet, MTYPE_FILEREQ); - - packLEDWord(&packet, WORD(18 + wDescrLen + wFilesLen + 1)); // Remaining length - packLEDWord(&packet, DWORD(wDescrLen)); // Description - packBuffer(&packet, (LPBYTE)szDescrAnsi, wDescrLen); - packWord(&packet, 0x8c82); // Unknown (port?), seen 0x80F6 - packWord(&packet, 0x0222); // Unknown, seen 0x2e01 - packLEWord(&packet, WORD(wFilesLen + 1)); - packBuffer(&packet, (LPBYTE)szFilesAnsi, wFilesLen + 1); - packLEDWord(&packet, ft->dwTotalSize); - packLEDWord(&packet, 0x0008c82); // Unknown, (seen 0xf680 ~33000) - - SAFE_FREE(&szFilesAnsi); - SAFE_FREE(&szDescrAnsi); - - // Pack request server ack TLV - if (nAckType == ACKTYPE_SERVER) - packDWord(&packet, 0x00030000); // TLV(3) - - // Send the monster - sendServPacket(&packet); -} - - -/* also sends rejections */ -void CIcqProto::icq_sendFileAcceptServv8(DWORD dwUin, DWORD TS1, DWORD TS2, DWORD dwCookie, const char *szFiles, const char *szDescr, DWORD dwTotalSize, WORD wPort, BOOL accepted, int nAckType) -{ - icq_packet packet; - char *szFilesAnsi = nullptr, *szDescrAnsi = nullptr; - - /* if !accepted, szDescr == szReason, szFiles = "" */ - - if (!accepted) szFiles = ""; - - if (!utf8_decode(szFiles, &szFilesAnsi)) - szFilesAnsi = _strdup(szFiles); // Legacy fix - - if (!utf8_decode(szDescr, &szDescrAnsi)) - szDescrAnsi = _strdup(szDescr); // Legacy fix - - size_t wDescrLen = mir_strlen(szDescrAnsi); - size_t wFilesLen = mir_strlen(szFilesAnsi); - - // 202 + UIN len + file description (no null) + file name (null included) - // Packet size = Flap length + 4 - size_t wFlapLen = 178 + wDescrLen + wFilesLen + (nAckType == ACKTYPE_SERVER ? 4 : 0); - packServMsgSendHeader(&packet, dwCookie, TS1, TS2, dwUin, nullptr, 2, wFlapLen); - - // TLV(5) header - packServTLV5HeaderMsg(&packet, 138 + wDescrLen + wFilesLen, TS1, TS2, 2); - - // Port & IP information - packServDCInfo(&packet, this, !accepted); - - // TLV(0x2711) header - packServTLV2711Header(&packet, (WORD)dwCookie, ICQ_VERSION, MTYPE_PLUGIN, 0, (WORD)(accepted ? 0 : 1), 0, 69 + wDescrLen + wFilesLen); - // - packEmptyMsg(&packet); // Message (unused) - - packPluginTypeId(&packet, MTYPE_FILEREQ); - - packLEDWord(&packet, DWORD(18 + wDescrLen + wFilesLen + 1)); // Remaining length - packLEDWord(&packet, DWORD(wDescrLen)); // Description - packBuffer(&packet, (LPBYTE)szDescrAnsi, wDescrLen); - packWord(&packet, wPort); // Port - packWord(&packet, 0x00); // Unknown - packLEWord(&packet, WORD(wFilesLen + 1)); - packBuffer(&packet, (LPBYTE)szFilesAnsi, wFilesLen + 1); - packLEDWord(&packet, dwTotalSize); - packLEDWord(&packet, (DWORD)wPort); // Unknown - - SAFE_FREE(&szFilesAnsi); - SAFE_FREE(&szDescrAnsi); - - // Pack request server ack TLV - if (nAckType == ACKTYPE_SERVER) { - packDWord(&packet, 0x00030000); // TLV(3) - } - - // Send the monster - sendServPacket(&packet); -} - - -void CIcqProto::icq_sendFileAcceptServv7(DWORD dwUin, DWORD TS1, DWORD TS2, DWORD dwCookie, const char* szFiles, const char* szDescr, DWORD dwTotalSize, WORD wPort, BOOL accepted, int nAckType) -{ - icq_packet packet; - char *szFilesAnsi = nullptr, *szDescrAnsi = nullptr; - - /* if !accepted, szDescr == szReason, szFiles = "" */ - - if (!accepted) szFiles = ""; - - if (!utf8_decode(szFiles, &szFilesAnsi)) - szFilesAnsi = _strdup(szFiles); // Legacy fix - - if (!utf8_decode(szDescr, &szDescrAnsi)) - szDescrAnsi = _strdup(szDescr); // Legacy fix - - size_t wDescrLen = mir_strlen(szDescrAnsi); - size_t wFilesLen = mir_strlen(szFilesAnsi); - - // 150 + UIN len + file description (with null) + file name (2 nulls) - // Packet size = Flap length + 4 - size_t wFlapLen = 127 + wDescrLen + 1 + wFilesLen + (nAckType == ACKTYPE_SERVER ? 4 : 0); - packServMsgSendHeader(&packet, dwCookie, TS1, TS2, dwUin, nullptr, 2, wFlapLen); - - // TLV(5) header - packServTLV5HeaderMsg(&packet, 88 + wDescrLen + wFilesLen, TS1, TS2, 2); - - // Port & IP information - packServDCInfo(&packet, this, !accepted); - - // TLV(0x2711) header - packServTLV2711Header(&packet, (WORD)dwCookie, ICQ_VERSION, MTYPE_FILEREQ, 0, (WORD)(accepted ? 0 : 1), 0, 19 + wDescrLen + wFilesLen); - // - packLEWord(&packet, WORD(wDescrLen + 1)); // Description - packBuffer(&packet, (LPBYTE)szDescrAnsi, wDescrLen + 1); - packWord(&packet, wPort); // Port - packWord(&packet, 0x00); // Unknown - packLEWord(&packet, WORD(wFilesLen + 2)); - packBuffer(&packet, (LPBYTE)szFilesAnsi, wFilesLen + 1); - packByte(&packet, 0); - packLEDWord(&packet, dwTotalSize); - packLEDWord(&packet, (DWORD)wPort); // Unknown - - SAFE_FREE(&szFilesAnsi); - SAFE_FREE(&szDescrAnsi); - - // Pack request server ack TLV - if (nAckType == ACKTYPE_SERVER) - packDWord(&packet, 0x00030000); // TLV(3) - - // Send the monster - sendServPacket(&packet); -} - -void CIcqProto::icq_sendFileAcceptServ(DWORD dwUin, filetransfer *ft, int nAckType) -{ - char *szDesc = ft->szDescription; - - if (ft->bEmptyDesc) szDesc = ""; // keep empty if it originally was (Trillian workaround) - - if (ft->nVersion >= 8) { - icq_sendFileAcceptServv8(dwUin, ft->pMessage.dwMsgID1, ft->pMessage.dwMsgID2, ft->dwCookie, ft->szFilename, szDesc, ft->dwTotalSize, wListenPort, TRUE, nAckType); - debugLogA("Sent file accept v%u through server, port %u", 8, wListenPort); - } - else { - icq_sendFileAcceptServv7(dwUin, ft->pMessage.dwMsgID1, ft->pMessage.dwMsgID2, ft->dwCookie, ft->szFilename, szDesc, ft->dwTotalSize, wListenPort, TRUE, nAckType); - debugLogA("Sent file accept v%u through server, port %u", 7, wListenPort); - } -} - -void CIcqProto::icq_sendFileDenyServ(DWORD dwUin, filetransfer *ft, const char *szReason, int nAckType) -{ - if (ft->nVersion >= 8) { - icq_sendFileAcceptServv8(dwUin, ft->pMessage.dwMsgID1, ft->pMessage.dwMsgID2, ft->dwCookie, ft->szFilename, szReason, ft->dwTotalSize, wListenPort, FALSE, nAckType); - debugLogA("Sent file deny v%u through server", 8); - } - else { - icq_sendFileAcceptServv7(dwUin, ft->pMessage.dwMsgID1, ft->pMessage.dwMsgID2, ft->dwCookie, ft->szFilename, szReason, ft->dwTotalSize, wListenPort, FALSE, nAckType); - debugLogA("Sent file deny v%u through server", 7); - } -} - -void CIcqProto::icq_sendAwayMsgReplyServ(DWORD dwUin, DWORD dwMsgID1, DWORD dwMsgID2, WORD wCookie, WORD wVersion, BYTE msgType, char** szMsg) -{ - MCONTACT hContact = HContactFromUIN(dwUin, nullptr); - - if (validateStatusMessageRequest(hContact, msgType)) { - NotifyEventHooks(m_modeMsgsEvent, (WPARAM)msgType, (LPARAM)dwUin); - - mir_cslock l(m_modeMsgsMutex); - - if (szMsg && *szMsg) { - char *pszMsg = nullptr; - WORD wReplyVersion = ICQ_VERSION; - - if (wVersion >= 9) { - pszMsg = *szMsg; - wReplyVersion = 9; - } - else { // only v9 protocol supports UTF-8 mode messagees - size_t wMsgLen = mir_strlen(*szMsg) + 1; - char *szAnsiMsg = (char*)_alloca(wMsgLen); - - utf8_decode_static(*szMsg, szAnsiMsg, wMsgLen); - pszMsg = szAnsiMsg; - } - - // limit msg len to max snac size - we get disconnected if exceeded - size_t wMsgLen = mir_strlen(pszMsg); - if (wMsgLen > MAX_MESSAGESNACSIZE) - wMsgLen = MAX_MESSAGESNACSIZE; - - icq_packet packet; - packServAdvancedMsgReply(&packet, dwUin, nullptr, dwMsgID1, dwMsgID2, wCookie, wReplyVersion, msgType, 3, wMsgLen + 3); - packLEWord(&packet, WORD(wMsgLen + 1)); - packBuffer(&packet, (LPBYTE)pszMsg, wMsgLen); - packByte(&packet, 0); - - sendServPacket(&packet); - } - } -} - - -void CIcqProto::icq_sendAwayMsgReplyServExt(DWORD dwUin, char *szUID, DWORD dwMsgID1, DWORD dwMsgID2, WORD wCookie, WORD wVersion, BYTE msgType, char **szMsg) -{ - MCONTACT hContact = HContactFromUID(dwUin, szUID, nullptr); - - if (validateStatusMessageRequest(hContact, msgType)) { - NotifyEventHooks(m_modeMsgsEvent, (WPARAM)msgType, (LPARAM)dwUin); - - mir_cslock l(m_modeMsgsMutex); - - if (szMsg && *szMsg) { - char *pszMsg = nullptr; - WORD wReplyVersion = ICQ_VERSION; - - if (wVersion >= 9) - pszMsg = *szMsg; - else { // only v9 protocol supports UTF-8 mode messagees - wReplyVersion = 8; - - size_t wMsgLen = mir_strlen(*szMsg) + 1; - char *szAnsiMsg = (char*)_alloca(wMsgLen); - - utf8_decode_static(*szMsg, szAnsiMsg, wMsgLen); - pszMsg = szAnsiMsg; - } - // convert to HTML - char *mng = MangleXml(pszMsg, mir_strlen(pszMsg)); - pszMsg = (char*)SAFE_MALLOC(mir_strlen(mng) + 28); - mir_strcpy(pszMsg, ""); /// TODO: add support for RTL & user customizable font - mir_strcat(pszMsg, mng); - SAFE_FREE(&mng); - mir_strcat(pszMsg, ""); - - // limit msg len to max snac size - we get disconnected if exceeded /// FIXME: correct HTML cutting - size_t wMsgLen = mir_strlen(pszMsg); - if (wMsgLen > MAX_MESSAGESNACSIZE) - wMsgLen = MAX_MESSAGESNACSIZE; - - icq_packet packet; - packServAdvancedMsgReply(&packet, dwUin, szUID, dwMsgID1, dwMsgID2, wCookie, wReplyVersion, MTYPE_PLUGIN, 0, wMsgLen + 27 + getPluginTypeIdLen(msgType)); - packLEWord(&packet, 0); // Message size - packPluginTypeId(&packet, msgType); - - packLEDWord(&packet, DWORD(wMsgLen + 21)); - packLEDWord(&packet, DWORD(wMsgLen)); - packBuffer(&packet, (LPBYTE)pszMsg, wMsgLen); - - packLEDWord(&packet, 0x0D); - packBuffer(&packet, (LPBYTE)"text/x-aolrtf", 0x0D); - - sendServPacket(&packet); - SAFE_FREE(&pszMsg); - } - } -} - - -void CIcqProto::icq_sendAdvancedMsgAck(DWORD dwUin, DWORD dwTimestamp, DWORD dwTimestamp2, WORD wCookie, BYTE bMsgType, BYTE bMsgFlags) -{ - icq_packet packet; - packServAdvancedMsgReply(&packet, dwUin, nullptr, dwTimestamp, dwTimestamp2, wCookie, ICQ_VERSION, bMsgType, bMsgFlags, 11); - packEmptyMsg(&packet); // Status message - packMsgColorInfo(&packet); - - sendServPacket(&packet); -} - - -void CIcqProto::icq_sendContactsAck(DWORD dwUin, char *szUid, DWORD dwMsgID1, DWORD dwMsgID2) -{ - icq_packet packet; - packServMsgSendHeader(&packet, 0, dwMsgID1, dwMsgID2, dwUin, szUid, 2, 0x1E); - packServTLV5HeaderBasic(&packet, 0, dwMsgID1, dwMsgID2, 2, MCAP_CONTACTS); - - sendServPacket(&packet); -} - - -// Searches - -DWORD CIcqProto::SearchByUin(DWORD dwUin) -{ - WORD wInfoLen; - icq_packet pBuffer; // I reuse the ICQ packet type as a generic buffer - // I should be ashamed! ;) - if (m_bLegacyFix) { - // Calculate data size - wInfoLen = 8; - - // Initialize our handy data buffer - pBuffer.wPlace = 0; - pBuffer.pData = (BYTE *)_alloca(wInfoLen); - pBuffer.wLen = wInfoLen; - - // Initialize our handy data buffer - packLEWord(&pBuffer, TLV_UIN); - packLEWord(&pBuffer, 0x0004); - packLEDWord(&pBuffer, dwUin); - - // Send it off for further packing - return sendTLVSearchPacket(SEARCHTYPE_UID, (char*)pBuffer.pData, META_SEARCH_UIN, wInfoLen, FALSE); - } - - // Calculate data size - wInfoLen = 4 + getUINLen(dwUin); - - // Initialize our handy data buffer - pBuffer.wPlace = 0; - pBuffer.pData = (BYTE *)_alloca(wInfoLen); - pBuffer.wLen = wInfoLen; - - // Initialize our handy data buffer - packTLVUID(&pBuffer, 0x32, dwUin, nullptr); - - // Send it off for further packing - return sendDirectorySearchPacket(pBuffer.pData, wInfoLen, 0, FALSE); -} - - -DWORD CIcqProto::SearchByNames(const char *pszNick, const char *pszFirstName, const char *pszLastName, WORD wPage) -{ // use directory search like ICQ6 does - size_t wInfoLen = 0; - icq_packet pBuffer; // I reuse the ICQ packet type as a generic buffer - // I should be ashamed! ;) - if (m_bLegacyFix) { - // Legacy protocol uses ANSI-string searches - - char* pszNickAnsi = nullptr; - if (!utf8_decode(pszNick, &pszNickAnsi)) - pszNickAnsi = _strdup(pszNick); - - char* pszFirstNameAnsi = nullptr; - if (!utf8_decode(pszFirstName, &pszFirstNameAnsi)) - pszFirstNameAnsi = _strdup(pszFirstName); - - char* pszLastNameAnsi = nullptr; - if (!utf8_decode(pszLastName, &pszLastNameAnsi)) - pszLastNameAnsi = _strdup(pszLastName); - - size_t wNickLen = mir_strlen(pszNickAnsi); - size_t wFirstLen = mir_strlen(pszFirstNameAnsi); - size_t wLastLen = mir_strlen(pszLastNameAnsi); - - _ASSERTE(wFirstLen || wLastLen || wNickLen); - - // Calculate data size - if (wFirstLen > 0) - wInfoLen = wFirstLen + 7; - if (wLastLen > 0) - wInfoLen += wLastLen + 7; - if (wNickLen > 0) - wInfoLen += wNickLen + 7; - - // Initialize our handy data buffer - pBuffer.wPlace = 0; - pBuffer.pData = (BYTE *)_alloca(wInfoLen); - pBuffer.wLen = WORD(wInfoLen); - - size_t pBufferPos = 0; - - // Pack the search details - if (wFirstLen > 0) - packLETLVLNTS(&pBuffer.pData, &pBufferPos, pszFirstNameAnsi, TLV_FIRSTNAME); - - if (wLastLen > 0) - packLETLVLNTS(&pBuffer.pData, &pBufferPos, pszLastNameAnsi, TLV_LASTNAME); - - if (wNickLen > 0) - packLETLVLNTS(&pBuffer.pData, &pBufferPos, pszNickAnsi, TLV_NICKNAME); - - SAFE_FREE(&pszFirstNameAnsi); - SAFE_FREE(&pszLastNameAnsi); - SAFE_FREE(&pszNickAnsi); - - // Send it off for further packing - return sendTLVSearchPacket(SEARCHTYPE_NAMES, (char*)pBuffer.pData, META_SEARCH_GENERIC, wInfoLen, FALSE); - } - - size_t wNickLen = mir_strlen(pszNick); - size_t wFirstLen = mir_strlen(pszFirstName); - size_t wLastLen = mir_strlen(pszLastName); - - _ASSERTE(wFirstLen || wLastLen || wNickLen); - - // Calculate data size - if (wFirstLen) - wInfoLen = wFirstLen + 4; - if (wLastLen) - wInfoLen += wLastLen + 4; - if (wNickLen) - wInfoLen += wNickLen + 4; - - // Initialize our handy data buffer - pBuffer.wPlace = 0; - pBuffer.pData = (BYTE *)_alloca(wInfoLen); - pBuffer.wLen = WORD(wInfoLen); - - // Pack the search details - if (wNickLen) - packTLV(&pBuffer, 0x78, wNickLen, (PBYTE)pszNick); - - if (wLastLen) - packTLV(&pBuffer, 0x6E, wLastLen, (PBYTE)pszLastName); - - if (wFirstLen) - packTLV(&pBuffer, 0x64, wFirstLen, (PBYTE)pszFirstName); - - // Send it off for further packing - if (wInfoLen) - return sendDirectorySearchPacket(pBuffer.pData, wInfoLen, wPage, FALSE); - else - return 0; // Failure -} - -DWORD CIcqProto::SearchByMail(const char* pszEmail) -{ - size_t wEmailLen = mir_strlen(pszEmail); - _ASSERTE(wEmailLen); - if (wEmailLen <= 0) - return 0; - - // Calculate data size - size_t wInfoLen = wEmailLen + 7; - - // Initialize our handy data buffer - BYTE *pBuffer = (BYTE *)_alloca(wInfoLen); - size_t pBufferPos = 0; - - // Pack the search details - packLETLVLNTS(&pBuffer, &pBufferPos, pszEmail, TLV_EMAIL); - - // Send it off for further packing - return sendTLVSearchPacket(SEARCHTYPE_EMAIL, (char*)pBuffer, META_SEARCH_EMAIL, wInfoLen, FALSE); -} - -DWORD CIcqProto::sendDirectorySearchPacket(const BYTE *pSearchData, size_t wDataLen, WORD wPage, BOOL bOnlineUsersOnly) -{ - _ASSERTE(pSearchData); - _ASSERTE(wDataLen >= 4); - - cookie_directory_data *pCookieData = (cookie_directory_data*)SAFE_MALLOC(sizeof(cookie_directory_data)); - if (pCookieData == nullptr) - return 0; - - pCookieData->bRequestType = DIRECTORYREQUEST_SEARCH; - DWORD dwCookie = AllocateCookie(CKT_DIRECTORY_QUERY, 0, NULL, (void*)pCookieData); - - // Pack headers - icq_packet packet; - packServIcqDirectoryHeader(&packet, this, wDataLen + (bOnlineUsersOnly ? 14 : 8), META_DIRECTORY_QUERY, DIRECTORY_QUERY_INFO, (WORD)dwCookie); - packWord(&packet, 0x02); - - // Pack requested page number - packWord(&packet, wPage); - - // Pack search data - packWord(&packet, 0x0001); - packWord(&packet, WORD(wDataLen + (bOnlineUsersOnly ? 6 : 0))); - packBuffer(&packet, pSearchData, wDataLen); - - if (bOnlineUsersOnly) // Pack "Online users only" flag - packTLVWord(&packet, 0x136, 1); - - // Go! - sendServPacket(&packet); - return dwCookie; -} - -DWORD CIcqProto::sendTLVSearchPacket(BYTE bType, char* pSearchDataBuf, WORD wSearchType, size_t wInfoLen, BOOL bOnlineUsersOnly) -{ - _ASSERTE(pSearchDataBuf); - _ASSERTE(wInfoLen >= 4); - - cookie_search *pCookie = (cookie_search*)SAFE_MALLOC(sizeof(cookie_search)); - if (!pCookie) - return 0; - - pCookie->bSearchType = bType; - DWORD dwCookie = AllocateCookie(CKT_SEARCH, 0, 0, pCookie); - - // Pack headers - icq_packet packet; - packServIcqExtensionHeader(&packet, this, wInfoLen + (wSearchType == META_SEARCH_GENERIC ? 7 : 2), CLI_META_INFO_REQ, (WORD)dwCookie); - - // Pack search type - packLEWord(&packet, wSearchType); - - // Pack search data - packBuffer(&packet, (LPBYTE)pSearchDataBuf, wInfoLen); - - if (wSearchType == META_SEARCH_GENERIC && bOnlineUsersOnly) { // Pack "Online users only" flag - only for generic search - BYTE bData = 1; - packTLV(&packet, TLV_ONLINEONLY, 1, &bData); - } - - // Go! - sendServPacket(&packet); - return dwCookie; -} - -DWORD CIcqProto::icq_sendAdvancedSearchServ(BYTE* fieldsBuffer, size_t bufferLen) -{ - cookie_search *pCookie = (cookie_search*)SAFE_MALLOC(sizeof(cookie_search)); - if (pCookie == nullptr) - return 0; - - pCookie->bSearchType = SEARCHTYPE_DETAILS; - DWORD dwCookie = AllocateCookie(CKT_SEARCH, 0, 0, pCookie); - - icq_packet packet; - packServIcqExtensionHeader(&packet, this, bufferLen, CLI_META_INFO_REQ, (WORD)dwCookie); - packBuffer(&packet, (LPBYTE)fieldsBuffer, bufferLen); - sendServPacket(&packet); - - return dwCookie; -} - -DWORD CIcqProto::icq_searchAimByEmail(const char* pszEmail, DWORD dwSearchId) -{ - cookie_search *pCookie; - if (!FindCookie(dwSearchId, nullptr, (void**)&pCookie)) { - dwSearchId = 0; - pCookie = (cookie_search*)SAFE_MALLOC(sizeof(cookie_search)); - pCookie->bSearchType = SEARCHTYPE_EMAIL; - } - - if (!pCookie) - return 0; - - pCookie->dwMainId = dwSearchId; - pCookie->szObject = null_strdup(pszEmail); - DWORD dwCookie = AllocateCookie(CKT_SEARCH, ICQ_LOOKUP_REQUEST, 0, pCookie); - - size_t wEmailLen = mir_strlen(pszEmail); - icq_packet packet; - serverPacketInit(&packet, 10 + wEmailLen); - packFNACHeader(&packet, ICQ_LOOKUP_FAMILY, ICQ_LOOKUP_REQUEST, 0, dwCookie); - packBuffer(&packet, (LPBYTE)pszEmail, wEmailLen); - - sendServPacket(&packet); - - return dwCookie; -} - -DWORD CIcqProto::icq_changeUserPasswordServ(const char *szPassword) -{ - size_t wPasswordLen = mir_strlen(szPassword); - DWORD dwCookie = GenerateCookie(0); - - icq_packet packet; - packServIcqExtensionHeader(&packet, this, wPasswordLen + 4, CLI_META_INFO_REQ, (WORD)dwCookie, ICQ_META_SRV_UPDATE); - packLEWord(&packet, META_SET_PASSWORD_REQ); - packLEWord(&packet, WORD(wPasswordLen)); - packBuffer(&packet, (BYTE*)szPassword, wPasswordLen); - sendServPacket(&packet); - - return dwCookie; -} - -DWORD CIcqProto::icq_changeUserDirectoryInfoServ(const BYTE *pData, size_t wDataLen, BYTE bRequestType) -{ - cookie_directory_data *pCookieData = (cookie_directory_data*)SAFE_MALLOC(sizeof(cookie_directory_data)); - pCookieData->bRequestType = bRequestType; - DWORD dwCookie = AllocateCookie(CKT_DIRECTORY_UPDATE, 0, NULL, pCookieData); - - icq_packet packet; - packServIcqDirectoryHeader(&packet, this, wDataLen + 4, META_DIRECTORY_UPDATE, DIRECTORY_SET_INFO, (WORD)dwCookie, ICQ_META_SRV_UPDATE); - packWord(&packet, 0x0003); - packWord(&packet, WORD(wDataLen)); - packBuffer(&packet, pData, wDataLen); - sendServPacket(&packet); - - return dwCookie; -} - -DWORD CIcqProto::icq_sendSMSServ(const char *szPhoneNumber, const char *szMsg) -{ - DWORD dwCookie; - WORD wBufferLen; - char *szBuffer = nullptr; - char szTime[30]; - time_t now = time(0); - strftime(szTime, sizeof(szTime), "%a, %d %b %Y %H:%M:%S GMT", gmtime(&now)); - /* Sun, 00 Jan 0000 00:00:00 GMT */ - - char *szMyNick = null_strdup(_T2A(Clist_GetContactDisplayName(0))); - size_t nBufferSize = 1 + mir_strlen(szMyNick) + mir_strlen(szPhoneNumber) + mir_strlen(szMsg) + sizeof("1252utf80000000000Yes"); - - if (szBuffer = (char *)_alloca(nBufferSize)) { - wBufferLen = mir_snprintf(szBuffer, nBufferSize, - "" - "" - "%s" /* phone number */ - "" - "" - "%s" /* body */ - "" - "" - "1252" - "" - "" - "utf8" - "" - "" - "%u" /* my UIN */ - "" - "" - "%s" /* my nick */ - "" - "" - "Yes" - "" - "" - "", - szPhoneNumber, szMsg, m_dwLocalUIN, szMyNick, szTime); - - dwCookie = GenerateCookie(0); - - icq_packet packet; - packServIcqExtensionHeader(&packet, this, wBufferLen + 27, CLI_META_INFO_REQ, (WORD)dwCookie); - packWord(&packet, 0x8214); /* send sms */ - packWord(&packet, 1); - packWord(&packet, 0x16); - packDWord(&packet, 0); - packDWord(&packet, 0); - packDWord(&packet, 0); - packDWord(&packet, 0); - packWord(&packet, 0); - packWord(&packet, WORD(wBufferLen + 1)); - packBuffer(&packet, (LPBYTE)szBuffer, wBufferLen + 1); - - sendServPacket(&packet); - } - else dwCookie = 0; - - SAFE_FREE((void**)&szMyNick); - return dwCookie; -} - -void CIcqProto::icq_sendGenericContact(DWORD dwUin, const char *szUid, WORD wFamily, WORD wSubType) -{ - int nUinLen = getUIDLen(dwUin, szUid); - - icq_packet packet; - serverPacketInit(&packet, nUinLen + 11); - packFNACHeader(&packet, wFamily, wSubType); - packUID(&packet, dwUin, szUid); - - sendServPacket(&packet); -} - -void CIcqProto::icq_sendNewContact(DWORD dwUin, const char *szUid) -{ - /* Try to add to temporary buddy list */ - icq_sendGenericContact(dwUin, szUid, ICQ_BUDDY_FAMILY, ICQ_USER_ADDTOTEMPLIST); -} - -void CIcqProto::icq_sendRemoveContact(DWORD dwUin, const char *szUid) -{ - /* Remove from temporary buddy list */ - icq_sendGenericContact(dwUin, szUid, ICQ_BUDDY_FAMILY, ICQ_USER_REMOVEFROMTEMPLIST); -} - -// list==0: visible list -// list==1: invisible list -void CIcqProto::icq_sendChangeVisInvis(MCONTACT hContact, DWORD dwUin, char* szUID, int list, int add) -{ - // TODO: This needs grouping & rate management - // Tell server to change our server-side contact visbility list - if (m_bSsiEnabled) { - WORD wContactId; - char* szSetting; - WORD wType; - - if (list == 0) { - wType = SSI_ITEM_PERMIT; - szSetting = DBSETTING_SERVLIST_PERMIT; - } - else { - wType = SSI_ITEM_DENY; - szSetting = DBSETTING_SERVLIST_DENY; - } - - if (add) { - // check if we should make the changes, this is 2nd level check - if (getWord(hContact, szSetting, 0) != 0) - return; - - // Add - wContactId = GenerateServerID(SSIT_ITEM, 0); - - icq_addServerPrivacyItem(hContact, dwUin, szUID, wContactId, wType); - - setWord(hContact, szSetting, wContactId); - } - else { - // Remove - wContactId = getWord(hContact, szSetting, 0); - - if (wContactId) { - icq_removeServerPrivacyItem(hContact, dwUin, szUID, wContactId, wType); - - delSetting(hContact, szSetting); - } - } - } - - // Notify server that we have changed - // our client side visibility list - if (list && m_iStatus == ID_STATUS_INVISIBLE) - return; - - if (!list && m_iStatus != ID_STATUS_INVISIBLE) - return; - - WORD wSnac = 0; - if (list && add) - wSnac = ICQ_CLI_ADDINVISIBLE; - else if (list && !add) - wSnac = ICQ_CLI_REMOVEINVISIBLE; - else if (!list && add) - wSnac = ICQ_CLI_ADDVISIBLE; - else if (!list && !add) - wSnac = ICQ_CLI_REMOVEVISIBLE; - - int nUinLen = getUIDLen(dwUin, szUID); - - icq_packet packet; - serverPacketInit(&packet, nUinLen + 11); - packFNACHeader(&packet, ICQ_BOS_FAMILY, wSnac); - packUID(&packet, dwUin, szUID); - sendServPacket(&packet); -} - -void CIcqProto::icq_sendEntireVisInvisList(int list) -{ - if (list) - sendEntireListServ(ICQ_BOS_FAMILY, ICQ_CLI_ADDINVISIBLE, BUL_INVISIBLE); - else - sendEntireListServ(ICQ_BOS_FAMILY, ICQ_CLI_ADDVISIBLE, BUL_VISIBLE); -} - -void CIcqProto::icq_sendRevokeAuthServ(DWORD dwUin, char *szUid) -{ - icq_sendGenericContact(dwUin, szUid, ICQ_LISTS_FAMILY, ICQ_LISTS_REVOKEAUTH); -} - -void CIcqProto::icq_sendGrantAuthServ(DWORD dwUin, const char *szUid, const char *szMsg) -{ - BYTE nUinlen = getUIDLen(dwUin, szUid); - - // Prepare custom utf-8 message - char *szUtfMsg = ansi_to_utf8(szMsg); - size_t nMsglen = mir_strlen(szUtfMsg); - - icq_packet packet; - serverPacketInit(&packet, 15 + nUinlen + nMsglen); - packFNACHeader(&packet, ICQ_LISTS_FAMILY, ICQ_LISTS_GRANTAUTH); - packUID(&packet, dwUin, szUid); - packWord(&packet, WORD(nMsglen)); - packBuffer(&packet, (LPBYTE)szUtfMsg, nMsglen); - packWord(&packet, 0); - - SAFE_FREE((void**)&szUtfMsg); - - sendServPacket(&packet); -} - -void CIcqProto::icq_sendAuthReqServ(DWORD dwUin, char *szUid, const char *szMsg) -{ - BYTE nUinlen = getUIDLen(dwUin, szUid); - size_t nMsglen = mir_strlen(szMsg); - - icq_packet packet; - serverPacketInit(&packet, 15 + nUinlen + nMsglen); - packFNACHeader(&packet, ICQ_LISTS_FAMILY, ICQ_LISTS_REQUESTAUTH); - packUID(&packet, dwUin, szUid); - packWord(&packet, WORD(nMsglen)); - packBuffer(&packet, (LPBYTE)szMsg, nMsglen); - packWord(&packet, 0); - - sendServPacket(&packet); -} - -void CIcqProto::icq_sendAuthResponseServ(DWORD dwUin, char* szUid, int auth, const wchar_t *szReason) -{ - BYTE nUinLen = getUIDLen(dwUin, szUid); - - // Prepare custom utf-8 reason - char *szUtfReason = make_utf8_string(szReason); - size_t nReasonLen = mir_strlen(szUtfReason); - - icq_packet packet; - serverPacketInit(&packet, 16 + nUinLen + nReasonLen); - packFNACHeader(&packet, ICQ_LISTS_FAMILY, ICQ_LISTS_CLI_AUTHRESPONSE); - packUID(&packet, dwUin, szUid); - packByte(&packet, (BYTE)auth); - packWord(&packet, WORD(nReasonLen)); - packBuffer(&packet, (LPBYTE)szUtfReason, nReasonLen); - packWord(&packet, 0); - - SAFE_FREE(&szUtfReason); - - sendServPacket(&packet); -} - -void CIcqProto::icq_sendYouWereAddedServ(DWORD dwUin, DWORD dwMyUin) -{ - DWORD dwID1 = time(0); - DWORD dwID2 = RandRange(0, 0x00FF); - - icq_packet packet; - packServMsgSendHeader(&packet, 0, dwID1, dwID2, dwUin, nullptr, 0x0004, 17); - packWord(&packet, 0x0005); // TLV(5) - packWord(&packet, 0x0009); - packLEDWord(&packet, dwMyUin); - packByte(&packet, MTYPE_ADDED); - packByte(&packet, 0); // msg-flags - packEmptyMsg(&packet); // NTS - packDWord(&packet, 0x00060000); // TLV(6) - sendServPacket(&packet); -} - -void CIcqProto::icq_sendXtrazRequestServ(DWORD dwUin, DWORD dwCookie, char* szBody, size_t nBodyLen, cookie_message_data *pCookieData) -{ - size_t wCoreLen = 11 + getPluginTypeIdLen(pCookieData->bMessageType) + nBodyLen; - - icq_packet packet; - packServMsgSendHeader(&packet, dwCookie, pCookieData->dwMsgID1, pCookieData->dwMsgID2, dwUin, nullptr, 2, 99 + wCoreLen); - - // TLV(5) header - packServTLV5HeaderMsg(&packet, 55 + wCoreLen, pCookieData->dwMsgID1, pCookieData->dwMsgID2, 1); - - // TLV(0x2711) header - packServTLV2711Header(&packet, (WORD)dwCookie, ICQ_VERSION, MTYPE_PLUGIN, 0, 0, 0x100, wCoreLen); - // - packEmptyMsg(&packet); - - packPluginTypeId(&packet, pCookieData->bMessageType); - - packLEDWord(&packet, DWORD(nBodyLen + 4)); - packLEDWord(&packet, DWORD(nBodyLen)); - packBuffer(&packet, (LPBYTE)szBody, nBodyLen); - - // Pack request server ack TLV - packDWord(&packet, 0x00030000); // TLV(3) - - // Send the monster - sendServPacket(&packet); -} - -void CIcqProto::icq_sendXtrazResponseServ(DWORD dwUin, DWORD dwMID, DWORD dwMID2, WORD wCookie, char* szBody, size_t nBodyLen, int nType) -{ - icq_packet packet; - packServAdvancedMsgReply(&packet, dwUin, nullptr, dwMID, dwMID2, wCookie, ICQ_VERSION, MTYPE_PLUGIN, 0, getPluginTypeIdLen(nType) + 11 + nBodyLen); - - packEmptyMsg(&packet); - - packPluginTypeId(&packet, nType); - - packLEDWord(&packet, DWORD(nBodyLen + 4)); - packLEDWord(&packet, DWORD(nBodyLen)); - packBuffer(&packet, (LPBYTE)szBody, nBodyLen); - - // Send the monster - sendServPacket(&packet); -} - -void CIcqProto::icq_sendReverseReq(directconnect *dc, DWORD dwCookie, cookie_message_data *pCookie) -{ - icq_packet packet; - packServMsgSendHeader(&packet, dwCookie, pCookie->dwMsgID1, pCookie->dwMsgID2, dc->dwRemoteUin, nullptr, 2, 0x47); - - packServTLV5HeaderBasic(&packet, 0x29, pCookie->dwMsgID1, pCookie->dwMsgID2, 0, MCAP_REVERSE_DC_REQ); - - packTLVWord(&packet, 0x0A, 1); // TLV: 0x0A Acktype: 1 for normal, 2 for ack - packDWord(&packet, 0x000F0000); // TLV: 0x0F empty - packDWord(&packet, 0x2711001B); // TLV: 0x2711 Content - // TLV(0x2711) data - packLEDWord(&packet, m_dwLocalUIN); // Our UIN - packDWord(&packet, dc->dwLocalExternalIP);// IP to connect to - packLEDWord(&packet, wListenPort); // Port to connect to - packByte(&packet, DC_NORMAL); // generic DC type - packDWord(&packet, dc->dwRemotePort); // unknown - packDWord(&packet, wListenPort); // port again ? - packLEWord(&packet, ICQ_VERSION); // DC Version - packLEDWord(&packet, dwCookie); // Req Cookie - - // Send the monster - sendServPacket(&packet); -} - -void CIcqProto::icq_sendReverseFailed(directconnect* dc, DWORD dwMsgID1, DWORD dwMsgID2, DWORD dwCookie) -{ - int nUinLen = getUINLen(dc->dwRemoteUin); - - icq_packet packet; - serverPacketInit(&packet, nUinLen + 74); - packFNACHeader(&packet, ICQ_MSG_FAMILY, ICQ_MSG_RESPONSE, 0, ICQ_MSG_RESPONSE << 0x10 | (dwCookie & 0x7FFF)); - packLEDWord(&packet, dwMsgID1); // Msg ID part 1 - packLEDWord(&packet, dwMsgID2); // Msg ID part 2 - packWord(&packet, 0x02); - packUIN(&packet, dc->dwRemoteUin); - packWord(&packet, 0x03); - packLEDWord(&packet, dc->dwRemoteUin); - packLEDWord(&packet, dc->dwRemotePort); - packLEDWord(&packet, wListenPort); - packLEWord(&packet, ICQ_VERSION); - packLEDWord(&packet, dwCookie); - - sendServPacket(&packet); -} - -// OSCAR file-transfer packets starts here -// -void CIcqProto::oft_sendFileRequest(DWORD dwUin, char *szUid, oscar_filetransfer *ft, const char *pszFiles, DWORD dwLocalInternalIP) -{ - size_t size = mir_strlen(ft->szDescription) + mir_strlen(pszFiles) + 160; - char *szCoolStr = (char *)_alloca(size); - mir_snprintf(szCoolStr, size, "%s%I64u1%s", pszFiles, ft->qwTotalSize, ft->szDescription); - szCoolStr = MangleXml(szCoolStr, mir_strlen(szCoolStr)); - - size_t wDataLen = 93 + mir_strlen(szCoolStr) + mir_strlen(pszFiles); - if (ft->bUseProxy) - wDataLen += 4; - - icq_packet packet; - packServMsgSendHeader(&packet, ft->dwCookie, ft->pMessage.dwMsgID1, ft->pMessage.dwMsgID2, dwUin, szUid, 2, wDataLen + 0x1E); - packServTLV5HeaderBasic(&packet, wDataLen, ft->pMessage.dwMsgID1, ft->pMessage.dwMsgID2, 0, MCAP_FILE_TRANSFER); - - packTLVWord(&packet, 0x0A, ++ft->wReqNum); // Request sequence - packDWord(&packet, 0x000F0000); // Unknown - packTLV(&packet, 0x0D, 5, (LPBYTE)"utf-8"); // Charset - packTLV(&packet, 0x0C, mir_strlen(szCoolStr), (LPBYTE)szCoolStr); // User message (CoolData XML) - SAFE_FREE(&szCoolStr); - if (ft->bUseProxy) { - packTLVDWord(&packet, 0x02, ft->dwProxyIP); // Proxy IP - packTLVDWord(&packet, 0x16, ft->dwProxyIP ^ 0x0FFFFFFFF); // Proxy IP check - } - else { - packTLVDWord(&packet, 0x02, dwLocalInternalIP); - packTLVDWord(&packet, 0x16, dwLocalInternalIP ^ 0x0FFFFFFFF); - } - packTLVDWord(&packet, 0x03, dwLocalInternalIP); // Client IP - if (ft->bUseProxy) { - packTLVWord(&packet, 0x05, ft->wRemotePort); - packTLVWord(&packet, 0x17, WORD(ft->wRemotePort ^ 0x0FFFF)); - packDWord(&packet, 0x00100000); // Proxy flag - } - else { - oscar_listener *pListener = (oscar_listener*)ft->listener; - packTLVWord(&packet, 0x05, pListener->wPort); - packTLVWord(&packet, 0x15, WORD((pListener->wPort) ^ 0x0FFFF)); - } - - // TLV(0x2711) - packWord(&packet, 0x2711); - packWord(&packet, WORD(9 + mir_strlen(pszFiles))); - packWord(&packet, WORD(ft->wFilesCount == 1 ? 1 : 2)); - packWord(&packet, ft->wFilesCount); - packDWord(&packet, (DWORD)ft->qwTotalSize); - packBuffer(&packet, (LPBYTE)pszFiles, mir_strlen(pszFiles) + 1); - - packTLV(&packet, 0x2712, 5, (LPBYTE)"utf-8"); - - // TLV(0x2713) - packWord(&packet, 0x2713); - packWord(&packet, 8); - packQWord(&packet, ft->qwTotalSize); - - sendServPacket(&packet); // Send the monster -} - - -void CIcqProto::oft_sendFileReply(DWORD dwUin, char *szUid, oscar_filetransfer *ft, WORD wResult) -{ - icq_packet packet; - packServMsgSendHeader(&packet, 0, ft->pMessage.dwMsgID1, ft->pMessage.dwMsgID2, dwUin, szUid, 2, 0x1E); - packServTLV5HeaderBasic(&packet, 0, ft->pMessage.dwMsgID1, ft->pMessage.dwMsgID2, wResult, MCAP_FILE_TRANSFER); - sendServPacket(&packet); -} - - -void CIcqProto::oft_sendFileAccept(DWORD dwUin, char *szUid, oscar_filetransfer *ft) -{ - oft_sendFileReply(dwUin, szUid, ft, 0x02); -} - -void CIcqProto::oft_sendFileResponse(DWORD dwUin, char *szUid, oscar_filetransfer *ft, WORD wResponse) -{ - icq_packet packet; - packServAdvancedReply(&packet, dwUin, szUid, ft->pMessage.dwMsgID1, ft->pMessage.dwMsgID2, 0, 4); - packWord(&packet, 0x02); // Length of following data - packWord(&packet, wResponse); // Response code - sendServPacket(&packet); -} - -void CIcqProto::oft_sendFileDeny(DWORD dwUin, char *szUid, oscar_filetransfer *ft) -{ - if (dwUin) // ICQ clients uses special deny file transfer - oft_sendFileResponse(dwUin, szUid, ft, 0x01); - else - oft_sendFileReply(dwUin, szUid, ft, 0x01); -} - -void CIcqProto::oft_sendFileCancel(DWORD dwUin, char *szUid, oscar_filetransfer *ft) -{ - oft_sendFileReply(dwUin, szUid, ft, 0x01); -} - -void CIcqProto::oft_sendFileRedirect(DWORD dwUin, char *szUid, oscar_filetransfer *ft, DWORD dwIP, WORD wPort, int bProxy) -{ - icq_packet packet; - packServMsgSendHeader(&packet, 0, ft->pMessage.dwMsgID1, ft->pMessage.dwMsgID2, dwUin, szUid, 2, bProxy ? 0x4a : 0x4e); - packServTLV5HeaderBasic(&packet, bProxy ? 0x2C : 0x30, ft->pMessage.dwMsgID1, ft->pMessage.dwMsgID2, 0, MCAP_FILE_TRANSFER); - // Connection point data - packTLVWord(&packet, 0x0A, ++ft->wReqNum); // Ack Type - packTLVWord(&packet, 0x14, 0x0A); // Unknown ? - packTLVDWord(&packet, 0x02, dwIP); // Internal IP / Proxy IP - packTLVDWord(&packet, 0x16, dwIP ^ 0x0FFFFFFFF); // IP Check ? - if (!bProxy) - packTLVDWord(&packet, 0x03, dwIP); - packTLVWord(&packet, 0x05, wPort); // Listening Port - packTLVWord(&packet, 0x17, WORD(wPort ^ 0x0FFFF)); // Port Check ? - if (bProxy) - packDWord(&packet, 0x00100000); // Proxy Flag - - sendServPacket(&packet); -} diff --git a/protocols/IcqOscarJ/src/stdpackets.h b/protocols/IcqOscarJ/src/stdpackets.h deleted file mode 100644 index cb5b8a683c..0000000000 --- a/protocols/IcqOscarJ/src/stdpackets.h +++ /dev/null @@ -1,43 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2008 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// Low-level functions that really sends data to server -// ----------------------------------------------------------------------------- - -#ifndef __STDPACKETS_H -#define __STDPACKETS_H - -struct icq_contactsend_s -{ - DWORD uin; - char *uid; - char *szNick; -}; - - -void packMsgColorInfo(icq_packet *packet); - -#endif /* __STDPACKETS_H */ diff --git a/protocols/IcqOscarJ/src/tlv.cpp b/protocols/IcqOscarJ/src/tlv.cpp deleted file mode 100644 index c2edc68dde..0000000000 --- a/protocols/IcqOscarJ/src/tlv.cpp +++ /dev/null @@ -1,341 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2009 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// Helper functions for Oscar TLV chains -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -/* set maxTlvs<=0 to get all TLVs in length, or a positive integer to get at most the first n */ -oscar_tlv_chain* readIntoTLVChain(BYTE **buf, size_t wLen, int maxTlvs) -{ - oscar_tlv_chain *now, *last = nullptr, *chain = nullptr; - WORD now_tlv_len; - - if (!buf || !wLen) - return nullptr; - - intptr_t len = wLen; - while (len > 0) { /* don't use unsigned variable for this check */ - now = (oscar_tlv_chain *)SAFE_MALLOC(sizeof(oscar_tlv_chain)); - - if (!now) { - disposeChain(&chain); - return nullptr; - } - - unpackWord(buf, &(now->tlv.wType)); - unpackWord(buf, &now_tlv_len); - now->tlv.wLen = now_tlv_len; - len -= 4; - - if (now_tlv_len < 1) - now->tlv.pData = nullptr; - else if (now_tlv_len <= len) { - now->tlv.pData = (BYTE *)SAFE_MALLOC(now_tlv_len); - if (now->tlv.pData) - memcpy(now->tlv.pData, *buf, now_tlv_len); - } - else { // the packet is shorter than it should be - SAFE_FREE((void**)&now); - return chain; // give at least the rest of chain - } - - if (chain) // keep the original order - last->next = now; - else - chain = now; - - last = now; - - len -= now_tlv_len; - *buf += now_tlv_len; - - if (--maxTlvs == 0) - break; - } - - return chain; -} - -// Returns a pointer to the TLV with type wType and number wIndex in the chain -// If wIndex = 1, the first matching TLV will be returned, if wIndex = 2, -// the second matching one will be returned. -// wIndex must be > 0 -oscar_tlv* oscar_tlv_chain::getTLV(WORD wType, WORD wIndex) -{ - int i = 0; - oscar_tlv_chain *list = this; - - while (list) { - if (list->tlv.wType == wType) - i++; - if (i >= wIndex) - return &list->tlv; - list = list->next; - } - - return nullptr; -} - -WORD oscar_tlv_chain::getChainLength() -{ - int len = 0; - oscar_tlv_chain *list = this; - - while (list) { - len += list->tlv.wLen + 4; - list = list->next; - } - return len; -} - -oscar_tlv* oscar_tlv_chain::putTLV(WORD wType, size_t wLen, BYTE *pData, BOOL bReplace) -{ - oscar_tlv *pTLV = getTLV(wType, 1); - - if (pTLV && bReplace) - SAFE_FREE((void**)&pTLV->pData); - else { - oscar_tlv_chain *last = this; - - while (last && last->next) - last = last->next; - - if (last) { - last->next = (oscar_tlv_chain*)SAFE_MALLOC(sizeof(oscar_tlv_chain)); - pTLV = &last->next->tlv; - pTLV->wType = wType; - } - } - if (pTLV) { - pTLV->wLen = WORD(wLen); - pTLV->pData = (PBYTE)SAFE_MALLOC(wLen); - memcpy(pTLV->pData, pData, wLen); - } - return pTLV; -} - -oscar_tlv_chain* oscar_tlv_chain::removeTLV(oscar_tlv *pTLV) -{ - oscar_tlv_chain *list = this, *prev = nullptr, *chain = this; - while (list) { - if (&list->tlv == pTLV) { - if (prev) // relink - prev->next = list->next; - else if (list->next) { // move second item's pTLV to the first item - list->tlv = list->next->tlv; - list = list->next; - } - else // result is an empty chain (NULL) - chain = nullptr; - // release chain item memory - SAFE_FREE((void**)&list->tlv.pData); - SAFE_FREE((void**)&list); - } - prev = list; - list = list->next; - } - - return chain; -} - -WORD oscar_tlv_chain::getLength(WORD wType, WORD wIndex) -{ - oscar_tlv *pTLV = getTLV(wType, wIndex); - if (pTLV) - return pTLV->wLen; - - return 0; -} - -/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ -/* Values are returned in MSB format */ -/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ - -DWORD oscar_tlv_chain::getDWord(WORD wType, WORD wIndex) -{ - DWORD dw = 0; - - oscar_tlv *pTLV = getTLV(wType, wIndex); - if (pTLV && pTLV->wLen >= 4) { - dw |= (*((pTLV->pData) + 0) << 24); - dw |= (*((pTLV->pData) + 1) << 16); - dw |= (*((pTLV->pData) + 2) << 8); - dw |= (*((pTLV->pData) + 3)); - } - - return dw; -} - -WORD oscar_tlv_chain::getWord(WORD wType, WORD wIndex) -{ - WORD w = 0; - - oscar_tlv *pTLV = getTLV(wType, wIndex); - if (pTLV && pTLV->wLen >= 2) { - w |= (*((pTLV->pData) + 0) << 8); - w |= (*((pTLV->pData) + 1)); - } - - return w; -} - -BYTE oscar_tlv_chain::getByte(WORD wType, WORD wIndex) -{ - BYTE b = 0; - - oscar_tlv *pTLV = getTLV(wType, wIndex); - if (pTLV && pTLV->wLen) - b = *(pTLV->pData); - - return b; -} - -int oscar_tlv_chain::getNumber(WORD wType, WORD wIndex) -{ - oscar_tlv *pTLV = getTLV(wType, wIndex); - if (pTLV) { - if (pTLV->wLen == 1) - return getByte(wType, wIndex); - if (pTLV->wLen == 2) - return getWord(wType, wIndex); - if (pTLV->wLen == 4) - return getDWord(wType, wIndex); - } - return 0; -} - -double oscar_tlv_chain::getDouble(WORD wType, WORD wIndex) -{ - oscar_tlv *pTLV = getTLV(wType, wIndex); - if (pTLV && pTLV->wLen == 8) { - BYTE *buf = pTLV->pData; - double d = 0; - - unpackQWord(&buf, (DWORD64*)&d); - - return d; - } - return 0; -} - -char* oscar_tlv_chain::getString(WORD wType, WORD wIndex) -{ - oscar_tlv *pTLV = getTLV(wType, wIndex); - if (pTLV) { - char *str = (char*)SAFE_MALLOC(pTLV->wLen + 1); /* For \0 */ - if (!str) - return nullptr; - - memcpy(str, pTLV->pData, pTLV->wLen); - str[pTLV->wLen] = '\0'; - return str; - } - - return nullptr; -} - -void disposeChain(oscar_tlv_chain **chain) -{ - if (!chain || !*chain) - return; - - oscar_tlv_chain *now = *chain; - while (now) { - oscar_tlv_chain *next = now->next; - - SAFE_FREE((void**)&now->tlv.pData); - SAFE_FREE((void**)&now); - now = next; - } - - *chain = nullptr; -} - -oscar_tlv_record_list* readIntoTLVRecordList(BYTE **buf, size_t wLen, int nCount) -{ - oscar_tlv_record_list *list = nullptr, *last = nullptr; - - while (wLen >= 2) { - WORD wRecordSize; - - unpackWord(buf, &wRecordSize); - wLen -= 2; - if (wRecordSize && wRecordSize <= wLen) { - oscar_tlv_record_list *pRecord = (oscar_tlv_record_list*)SAFE_MALLOC(sizeof(oscar_tlv_record_list)); - BYTE *pData = *buf; - - *buf += wRecordSize; - wLen -= wRecordSize; - - pRecord->item = readIntoTLVChain(&pData, wRecordSize, 0); - if (pRecord->item) { // keep the order - if (list) - last->next = pRecord; - else - list = pRecord; - - last = pRecord; - } - else SAFE_FREE((void**)&pRecord); - } - - if (--nCount == 0) - break; - } - return list; -} - -void disposeRecordList(oscar_tlv_record_list** list) -{ - if (!list || !*list) - return; - - oscar_tlv_record_list *now = *list; - - while (now) { - oscar_tlv_record_list *next = now->next; - - disposeChain(&now->item); - SAFE_FREE((void**)&now); - now = next; - } - - *list = nullptr; -} - -oscar_tlv_chain* oscar_tlv_record_list::getRecordByTLV(WORD wType, int nValue) -{ - oscar_tlv_record_list *list = this; - while (list) { - if (list->item && list->item->getTLV(wType, 1) && list->item->getNumber(wType, 1) == nValue) - return list->item; - list = list->next; - } - - return nullptr; -} diff --git a/protocols/IcqOscarJ/src/tlv.h b/protocols/IcqOscarJ/src/tlv.h deleted file mode 100644 index fb1d594cae..0000000000 --- a/protocols/IcqOscarJ/src/tlv.h +++ /dev/null @@ -1,76 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2008 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// ----------------------------------------------------------------------------- - -#ifndef __TLV_H -#define __TLV_H - -/*---------* Structures *--------------*/ - -struct oscar_tlv -{ - WORD wType; - WORD wLen; - BYTE *pData; -}; - -struct oscar_tlv_chain -{ - oscar_tlv tlv; - oscar_tlv_chain *next; - - WORD getChainLength(); - - oscar_tlv* getTLV(WORD wType, WORD wIndex); - oscar_tlv* putTLV(WORD wType, size_t wLen, BYTE *pData, BOOL bReplace); - oscar_tlv_chain* removeTLV(oscar_tlv *tlv); - WORD getLength(WORD wType, WORD wIndex); - - DWORD getDWord(WORD wType, WORD wIndex); - WORD getWord(WORD wType, WORD wIndex); - BYTE getByte(WORD wType, WORD wIndex); - int getNumber(WORD wType, WORD wIndex); - double getDouble(WORD wType, WORD wIndex); - char* getString(WORD wType, WORD wIndex); -}; - - -struct oscar_tlv_record_list -{ - oscar_tlv_chain *item; - oscar_tlv_record_list *next; - - oscar_tlv_chain* getRecordByTLV(WORD wType, int nValue); -}; - -/*---------* Functions *---------------*/ - -oscar_tlv_chain* readIntoTLVChain(BYTE **buf, size_t wLen, int maxTlvs); -void disposeChain(oscar_tlv_chain** chain); - -oscar_tlv_record_list* readIntoTLVRecordList(BYTE **buf, size_t wLen, int nCount); -void disposeRecordList(oscar_tlv_record_list** list); - - -#endif /* __TLV_H */ diff --git a/protocols/IcqOscarJ/src/upload.cpp b/protocols/IcqOscarJ/src/upload.cpp deleted file mode 100644 index f6741d1e7c..0000000000 --- a/protocols/IcqOscarJ/src/upload.cpp +++ /dev/null @@ -1,86 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2001-2004 Richard Hughes, Martin Öberg -// Copyright © 2004-2009 Joe Kucera, Bio -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// ChangeInfo Plugin stuff -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -int CIcqProto::StringToListItemId(const char *szSetting, int def) -{ - int i; - - for (i = 0; i < settingCount; i++) - if (!mir_strcmp(szSetting, setting[i].szDbSetting)) - break; - - if (i == settingCount) - return def; - - FieldNamesItem *list = (FieldNamesItem*)setting[i].pList; - - char *szValue = getSettingStringUtf(NULL, szSetting, nullptr); - if (!szValue) - return def; - - for (i = 0; list[i].text; i++) - if (!mir_strcmp(list[i].text, szValue)) - break; - - SAFE_FREE(&szValue); - if (!list[i].text) return def; - - return list[i].code; -} - - -int ChangeInfoData::UploadSettings(void) -{ - if (!ppro->icqOnline()) { - MessageBox(hwndDlg, TranslateT("You are not currently connected to the ICQ network. You must be online in order to update your information on the server."), TranslateT("Change ICQ Details"), MB_OK); - return 0; - } - - hUpload[0] = (HANDLE)ppro->ChangeInfoEx(CIXT_FULL, 0); - - //password - char* tmp = ppro->GetUserPassword(TRUE); - if (tmp) { - if (mir_strlen(Password) > 0 && mir_strcmp(Password, tmp)) { - // update password in user info dialog (still open) - mir_strcpy(Password, tmp); - // update password in protocol - mir_strcpy(ppro->m_szPassword, tmp); - - hUpload[1] = (HANDLE)ppro->icq_changeUserPasswordServ(tmp); - - // password is stored in DB, update - char szPwd[PASSWORDMAXLEN + 1]; - if (ppro->GetUserStoredPassword(szPwd)) - ppro->setString("Password", tmp); - } - } - - return 1; -} diff --git a/protocols/IcqOscarJ/src/userinfotab.cpp b/protocols/IcqOscarJ/src/userinfotab.cpp deleted file mode 100644 index 305cc33a9a..0000000000 --- a/protocols/IcqOscarJ/src/userinfotab.cpp +++ /dev/null @@ -1,290 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- -// DESCRIPTION: -// -// Code for User details ICQ specific pages -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -#define SVS_NORMAL 0 -#define SVS_ZEROISUNSPEC 2 -#define SVS_IP 3 -#define SVS_SIGNED 6 -#define SVS_ICQVERSION 8 -#define SVS_TIMESTAMP 9 -#define SVS_STATUSID 10 - -extern const char *nameXStatus[]; - -///////////////////////////////////////////////////////////////////////////////////////// - -static void SetValue(CIcqProto* ppro, HWND hwndDlg, int idCtrl, MCONTACT hContact, char* szModule, char* szSetting, int special) -{ - DBVARIANT dbv = { 0 }; - char str[MAX_PATH]; - char* pstr = nullptr; - int unspecified = 0; - int bUtf = 0, bDbv = 0, bAlloc = 0; - - dbv.type = DBVT_DELETED; - - if ((hContact == NULL) && ((INT_PTR)szModule < 0x100)) { - dbv.type = (INT_PTR)szModule; - - switch ((INT_PTR)szModule) { - case DBVT_BYTE: - dbv.cVal = (INT_PTR)szSetting; - break; - case DBVT_WORD: - dbv.wVal = (INT_PTR)szSetting; - break; - case DBVT_DWORD: - dbv.dVal = (UINT_PTR)szSetting; - break; - case DBVT_ASCIIZ: - dbv.pszVal = pstr = szSetting; - break; - default: - unspecified = 1; - dbv.type = DBVT_DELETED; - } - } - else { - if (szModule == nullptr) - unspecified = 1; - else { - unspecified = db_get(hContact, szModule, szSetting, &dbv); - bDbv = 1; - } - } - - if (!unspecified) { - switch (dbv.type) { - case DBVT_BYTE: - unspecified = (special == SVS_ZEROISUNSPEC && dbv.bVal == 0); - pstr = _itoa(special == SVS_SIGNED ? dbv.cVal : dbv.bVal, str, 10); - break; - - case DBVT_WORD: - if (special == SVS_ICQVERSION) { - if (dbv.wVal != 0) { - char szExtra[80]; - - mir_snprintf(str, "%d", dbv.wVal); - pstr = str; - - if (hContact && ppro->IsDirectConnectionOpen(hContact, DIRECTCONN_STANDARD, 1)) { - ICQTranslateUtfStatic(LPGEN(" (DC Established)"), szExtra, _countof(szExtra)); - mir_strcat(str, (char*)szExtra); - bUtf = 1; - } - } - else - unspecified = 1; - } - else if (special == SVS_STATUSID) { - char *pszStatus = MirandaStatusToStringUtf(dbv.wVal); - BYTE bXStatus = ppro->getContactXStatus(hContact); - - if (bXStatus) { - char *pXName = ppro->getSettingStringUtf(hContact, DBSETTING_XSTATUS_NAME, nullptr); - if (pXName == nullptr) // give default name - pXName = ICQTranslateUtf(nameXStatus[bXStatus - 1]); - - mir_snprintf(str, "%s (%s)", pszStatus, pXName); - SAFE_FREE((void**)&pXName); - } - else strncpy_s(str, pszStatus, _TRUNCATE); - - bUtf = 1; - SAFE_FREE(&pszStatus); - pstr = str; - unspecified = 0; - } - else { - unspecified = (special == SVS_ZEROISUNSPEC && dbv.wVal == 0); - pstr = _itoa(special == SVS_SIGNED ? dbv.sVal : dbv.wVal, str, 10); - } - break; - - case DBVT_DWORD: - unspecified = (special == SVS_ZEROISUNSPEC && dbv.dVal == 0); - if (special == SVS_IP) { - struct in_addr ia; - ia.S_un.S_addr = htonl(dbv.dVal); - pstr = inet_ntoa(ia); - if (dbv.dVal == 0) - unspecified = 1; - } - else if (special == SVS_TIMESTAMP) { - if (dbv.dVal == 0) - unspecified = 1; - else - pstr = time2text(dbv.dVal); - } - else - pstr = _itoa(special == SVS_SIGNED ? dbv.lVal : dbv.dVal, str, 10); - break; - - case DBVT_ASCIIZ: - case DBVT_WCHAR: - unspecified = (special == SVS_ZEROISUNSPEC && dbv.pszVal[0] == '\0'); - if (!unspecified && pstr != szSetting) { - pstr = ppro->getSettingStringUtf(hContact, szModule, szSetting, nullptr); - bUtf = 1; - bAlloc = 1; - } - if (idCtrl == IDC_UIN) - SetDlgItemText(hwndDlg, IDC_UINSTATIC, TranslateT("ScreenName:")); - break; - - default: - pstr = str; - mir_strcpy(str, "???"); - break; - } - } - - EnableDlgItem(hwndDlg, idCtrl, !unspecified); - if (unspecified) - SetDlgItemText(hwndDlg, idCtrl, TranslateT("")); - else if (bUtf) - SetDlgItemTextUtf(hwndDlg, idCtrl, pstr); - else - SetDlgItemTextA(hwndDlg, idCtrl, pstr); - - if (bDbv) - db_free(&dbv); - - if (bAlloc) - SAFE_FREE(&pstr); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static INT_PTR CALLBACK IcqDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - break; - - case WM_NOTIFY: - switch (((LPNMHDR)lParam)->idFrom) { - case 0: - switch (((LPNMHDR)lParam)->code) { - case PSN_PARAMCHANGED: - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, ((PSHNOTIFY*)lParam)->lParam); - break; - - case PSN_INFOCHANGED: - CIcqProto * ppro = (CIcqProto*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - if (!ppro) - break; - - char* szProto; - MCONTACT hContact = (MCONTACT)((LPPSHNOTIFY)lParam)->lParam; - - if (hContact == NULL) - szProto = ppro->m_szModuleName; - else - szProto = GetContactProto(hContact); - - if (!szProto) - break; - - SetValue(ppro, hwndDlg, IDC_UIN, hContact, szProto, UNIQUEIDSETTING, SVS_NORMAL); - SetValue(ppro, hwndDlg, IDC_ONLINESINCE, hContact, szProto, "LogonTS", SVS_TIMESTAMP); - SetValue(ppro, hwndDlg, IDC_IDLETIME, hContact, szProto, "IdleTS", SVS_TIMESTAMP); - SetValue(ppro, hwndDlg, IDC_IP, hContact, szProto, "IP", SVS_IP); - SetValue(ppro, hwndDlg, IDC_REALIP, hContact, szProto, "RealIP", SVS_IP); - - if (hContact) { - SetValue(ppro, hwndDlg, IDC_PORT, hContact, szProto, "UserPort", SVS_ZEROISUNSPEC); - SetValue(ppro, hwndDlg, IDC_VERSION, hContact, szProto, "Version", SVS_ICQVERSION); - SetValue(ppro, hwndDlg, IDC_MIRVER, hContact, szProto, "MirVer", SVS_ZEROISUNSPEC); - if (ppro->getByte(hContact, "ClientID", 0)) - ppro->setDword(hContact, "TickTS", 0); - SetValue(ppro, hwndDlg, IDC_SYSTEMUPTIME, hContact, szProto, "TickTS", SVS_TIMESTAMP); - SetValue(ppro, hwndDlg, IDC_STATUS, hContact, szProto, "Status", SVS_STATUSID); - } - else { - MFileVersion v; - Miranda_GetFileVersion(&v); - - char str[MAX_PATH]; - mir_snprintf(str, "Miranda NG %d.%d.%d.%d (ICQ %s)", v[0], v[1], v[2], v[3], __VERSION_STRING_DOTS); - - SetValue(ppro, hwndDlg, IDC_PORT, hContact, (char*)DBVT_WORD, (char*)ppro->wListenPort, SVS_ZEROISUNSPEC); - SetValue(ppro, hwndDlg, IDC_VERSION, hContact, (char*)DBVT_WORD, (char*)ICQ_VERSION, SVS_ICQVERSION); - SetValue(ppro, hwndDlg, IDC_MIRVER, hContact, (char*)DBVT_ASCIIZ, str, SVS_ZEROISUNSPEC); - SetDlgItemText(hwndDlg, IDC_SUPTIME, TranslateT("Member since:")); - SetValue(ppro, hwndDlg, IDC_SYSTEMUPTIME, hContact, szProto, "MemberTS", SVS_TIMESTAMP); - SetValue(ppro, hwndDlg, IDC_STATUS, hContact, (char*)DBVT_WORD, (char*)ppro->m_iStatus, SVS_STATUSID); - } - } - } - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDCANCEL: - SendMessage(GetParent(hwndDlg), msg, wParam, lParam); - break; - } - break; - } - - return FALSE; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -int CIcqProto::OnUserInfoInit(WPARAM wParam, LPARAM lParam) -{ - if ((!IsICQContact(lParam)) && lParam) - return 0; - - OPTIONSDIALOGPAGE odp = {}; - odp.flags = ODPF_UNICODE | ODPF_USERINFOTAB | ODPF_DONTTRANSLATE; - odp.dwInitParam = LPARAM(this); - odp.szTitle.w = m_tszUserName; - - odp.pfnDlgProc = IcqDlgProc; - odp.position = -1900000000; - odp.szTab.w = LPGENW("Details"); - odp.pszTemplate = MAKEINTRESOURCEA(IDD_INFO_ICQ); - g_plugin.addUserInfo(wParam, &odp); - - if (!lParam) { - odp.szTab.w = LPGENW("Account"); - odp.position = -1899999999; - odp.pszTemplate = MAKEINTRESOURCEA(IDD_INFO_CHANGEINFO); - odp.pfnDlgProc = ChangeInfoDlgProc; - g_plugin.addUserInfo(wParam, &odp); - } - return 0; -} diff --git a/protocols/IcqOscarJ/src/utilities.cpp b/protocols/IcqOscarJ/src/utilities.cpp deleted file mode 100644 index 05d3358153..0000000000 --- a/protocols/IcqOscarJ/src/utilities.cpp +++ /dev/null @@ -1,1695 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- - -#include "stdafx.h" - -struct gateway_index -{ - HANDLE hConn; - DWORD dwIndex; -}; - -static mir_cs gatewayMutex; - -static gateway_index *gateways = nullptr; -static int gatewayCount = 0; - -static DWORD *spammerList = nullptr; -static int spammerListCount = 0; - - -void MoveDlgItem(HWND hwndDlg, int iItem, int left, int top, int width, int height) -{ - RECT rc; - - rc.left = left; - rc.top = top; - rc.right = left + width; - rc.bottom = top + height; - MapDialogRect(hwndDlg, &rc); - MoveWindow(GetDlgItem(hwndDlg, iItem), rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, FALSE); -} - - -void EnableDlgItem(HWND hwndDlg, UINT control, int state) -{ - EnableWindow(GetDlgItem(hwndDlg, control), state); -} - - -void ShowDlgItem(HWND hwndDlg, UINT control, int state) -{ - ShowWindow(GetDlgItem(hwndDlg, control), state); -} - - -void icq_EnableMultipleControls(HWND hwndDlg, const UINT *controls, int cControls, int state) -{ - for (int i = 0; i < cControls; i++) - EnableDlgItem(hwndDlg, controls[i], state); -} - - -void icq_ShowMultipleControls(HWND hwndDlg, const UINT *controls, int cControls, int state) -{ - for (int i = 0; i < cControls; i++) - ShowDlgItem(hwndDlg, controls[i], state); -} - - -// Maps the ICQ status flag (as seen in the status change SNACS) and returns -// a Miranda style status. -int IcqStatusToMiranda(WORD nIcqStatus) -{ - int nMirandaStatus; - - // :NOTE: The order in which the flags are compared are important! - // I dont like this method but it works. - - if (nIcqStatus & ICQ_STATUSF_INVISIBLE) - nMirandaStatus = ID_STATUS_INVISIBLE; - else - if (nIcqStatus & ICQ_STATUSF_DND) - nMirandaStatus = ID_STATUS_DND; - else - if (nIcqStatus & ICQ_STATUSF_OCCUPIED) - nMirandaStatus = ID_STATUS_OCCUPIED; - else - if (nIcqStatus & ICQ_STATUSF_NA) - nMirandaStatus = ID_STATUS_NA; - else - if (nIcqStatus & ICQ_STATUSF_AWAY) - nMirandaStatus = ID_STATUS_AWAY; - else - if (nIcqStatus & ICQ_STATUSF_FFC) - nMirandaStatus = ID_STATUS_FREECHAT; - else - // Can be discussed, but I think 'online' is the most generic ICQ status - nMirandaStatus = ID_STATUS_ONLINE; - - return nMirandaStatus; -} - -WORD MirandaStatusToIcq(int nMirandaStatus) -{ - WORD nIcqStatus; - - switch (nMirandaStatus) { - case ID_STATUS_ONLINE: - nIcqStatus = ICQ_STATUS_ONLINE; - break; - - case ID_STATUS_AWAY: - nIcqStatus = ICQ_STATUS_AWAY; - break; - - case ID_STATUS_OUTTOLUNCH: - case ID_STATUS_NA: - nIcqStatus = ICQ_STATUS_NA; - break; - - case ID_STATUS_ONTHEPHONE: - case ID_STATUS_OCCUPIED: - nIcqStatus = ICQ_STATUS_OCCUPIED; - break; - - case ID_STATUS_DND: - nIcqStatus = ICQ_STATUS_DND; - break; - - case ID_STATUS_INVISIBLE: - nIcqStatus = ICQ_STATUS_INVISIBLE; - break; - - case ID_STATUS_FREECHAT: - nIcqStatus = ICQ_STATUS_FFC; - break; - - case ID_STATUS_OFFLINE: - // Oscar doesnt have anything that maps to this status. This should never happen. - _ASSERTE(nMirandaStatus != ID_STATUS_OFFLINE); - nIcqStatus = 0; - break; - - default: - // Online seems to be a good default. - // Since it cant be offline, it must be a new type of online status. - nIcqStatus = ICQ_STATUS_ONLINE; - break; - } - - return nIcqStatus; -} - -int MirandaStatusToSupported(int nMirandaStatus) -{ - int nSupportedStatus; - - switch (nMirandaStatus) { - - // These status mode does not need any mapping - case ID_STATUS_ONLINE: - case ID_STATUS_AWAY: - case ID_STATUS_NA: - case ID_STATUS_OCCUPIED: - case ID_STATUS_DND: - case ID_STATUS_INVISIBLE: - case ID_STATUS_OFFLINE: - nSupportedStatus = nMirandaStatus; - break; - - case ID_STATUS_FREECHAT: - nSupportedStatus = ID_STATUS_ONLINE; - break; - - // This mode is not support and must be mapped to something else - case ID_STATUS_OUTTOLUNCH: - nSupportedStatus = ID_STATUS_NA; - break; - - // This mode is not support and must be mapped to something else - case ID_STATUS_ONTHEPHONE: - nSupportedStatus = ID_STATUS_OCCUPIED; - break; - - // This is not supposed to happen. - default: - _ASSERTE(0); - // Online seems to be a good default. - nSupportedStatus = ID_STATUS_ONLINE; - break; - } - - return nSupportedStatus; -} - -char* MirandaStatusToStringUtf(int mirandaStatus) -{ // return miranda status description in utf-8, use unicode service is possible - return make_utf8_string(Clist_GetStatusModeDescription(mirandaStatus, 0)); -} - -char** CIcqProto::MirandaStatusToAwayMsg(int nStatus) -{ - switch (nStatus) { - case ID_STATUS_ONLINE: - return &m_modeMsgs.szOnline; - - case ID_STATUS_AWAY: - return &m_modeMsgs.szAway; - - case ID_STATUS_NA: - return &m_modeMsgs.szNa; - - case ID_STATUS_OCCUPIED: - return &m_modeMsgs.szOccupied; - - case ID_STATUS_DND: - return &m_modeMsgs.szDnd; - - case ID_STATUS_FREECHAT: - return &m_modeMsgs.szFfc; - - default: - return nullptr; - } -} - -int AwayMsgTypeToStatus(int nMsgType) -{ - switch (nMsgType) { - case MTYPE_AUTOONLINE: - return ID_STATUS_ONLINE; - - case MTYPE_AUTOAWAY: - return ID_STATUS_AWAY; - - case MTYPE_AUTOBUSY: - return ID_STATUS_OCCUPIED; - - case MTYPE_AUTONA: - return ID_STATUS_NA; - - case MTYPE_AUTODND: - return ID_STATUS_DND; - - case MTYPE_AUTOFFC: - return ID_STATUS_FREECHAT; - - default: - return ID_STATUS_OFFLINE; - } -} - - -void SetGatewayIndex(HANDLE hConn, DWORD dwIndex) -{ - mir_cslock l(gatewayMutex); - - for (int i = 0; i < gatewayCount; i++) { - if (hConn == gateways[i].hConn) { - gateways[i].dwIndex = dwIndex; - return; - } - } - - gateways = (gateway_index *)SAFE_REALLOC(gateways, sizeof(gateway_index)* (gatewayCount + 1)); - gateways[gatewayCount].hConn = hConn; - gateways[gatewayCount].dwIndex = dwIndex; - gatewayCount++; -} - - -DWORD GetGatewayIndex(HANDLE hConn) -{ - mir_cslock l(gatewayMutex); - - for (int i = 0; i < gatewayCount; i++) - if (hConn == gateways[i].hConn) - return gateways[i].dwIndex; - - return 1; // this is default -} - - -void FreeGatewayIndex(HANDLE hConn) -{ - mir_cslock l(gatewayMutex); - - for (int i = 0; i < gatewayCount; i++) { - if (hConn == gateways[i].hConn) { - gatewayCount--; - memmove(&gateways[i], &gateways[i + 1], sizeof(gateway_index)* (gatewayCount - i)); - gateways = (gateway_index*)SAFE_REALLOC(gateways, sizeof(gateway_index)* gatewayCount); - - // Gateway found, exit loop - break; - } - } -} - - -void CIcqProto::AddToSpammerList(DWORD dwUIN) -{ - mir_cslock l(gatewayMutex); - - spammerList = (DWORD *)SAFE_REALLOC(spammerList, sizeof(DWORD)* (spammerListCount + 1)); - spammerList[spammerListCount] = dwUIN; - spammerListCount++; -} - - -BOOL CIcqProto::IsOnSpammerList(DWORD dwUIN) -{ - mir_cslock l(gatewayMutex); - - for (int i = 0; i < spammerListCount; i++) - if (dwUIN == spammerList[i]) - return TRUE; - - return FALSE; -} - - -// ICQ contacts cache - -void CIcqProto::AddToContactsCache(MCONTACT hContact, DWORD dwUin, const char *szUid) -{ - if (!hContact || (!dwUin && !szUid)) - return; - - icq_contacts_cache *cache_item = (icq_contacts_cache*)SAFE_MALLOC(sizeof(icq_contacts_cache)); - cache_item->hContact = hContact; - cache_item->dwUin = dwUin; - if (!dwUin) - cache_item->szUid = null_strdup(szUid); - - mir_cslock l(contactsCacheMutex); - contactsCache.insert(cache_item); -} - - -void CIcqProto::InitContactsCache() -{ - // build cache - mir_cslock l(contactsCacheMutex); - - for (auto &hContact : AccContacts()) { - DWORD dwUin; - uid_str szUid; - if (!getContactUid(hContact, &dwUin, &szUid)) - AddToContactsCache(hContact, dwUin, szUid); - } -} - - -void CIcqProto::UninitContactsCache(void) -{ - mir_cslock l(contactsCacheMutex); - - // cleanup the cache - for (auto &it : contactsCache) { - SAFE_FREE((void**)&it->szUid); - SAFE_FREE((void**)&it); - } - - contactsCache.destroy(); -} - - -void CIcqProto::DeleteFromContactsCache(MCONTACT hContact) -{ - mir_cslock l(contactsCacheMutex); - - for (auto &it : contactsCache) { - if (it->hContact == hContact) { - // Release memory - SAFE_FREE((void**)&it->szUid); - SAFE_FREE((void**)&it); - contactsCache.removeItem(&it); - break; - } - } -} - - -MCONTACT CIcqProto::HandleFromCacheByUid(DWORD dwUin, const char *szUid) -{ - icq_contacts_cache cache_item = { NULL, dwUin, szUid }; - - mir_cslock l(contactsCacheMutex); - // find in list - int i = contactsCache.getIndex(&cache_item); - if (i != -1) - return contactsCache[i]->hContact; - - return NULL; -} - - -MCONTACT CIcqProto::HContactFromUIN(DWORD dwUin, int *Added) -{ - if (Added) - *Added = 0; - - MCONTACT cc = HandleFromCacheByUid(dwUin, nullptr); - if (cc) - return cc; - - for (auto &hContact : AccContacts()) { - DWORD dwContactUin = getContactUin(hContact); - if (dwContactUin == dwUin) { - AddToContactsCache(hContact, dwUin, nullptr); - return hContact; - } - } - - // not present: add - if (Added) { - debugLogA("Attempt to create ICQ contact %u", dwUin); - - MCONTACT hContact = db_add_contact(); - if (!hContact) { - debugLogA("Failed to create ICQ contact %u", dwUin); - return INVALID_CONTACT_ID; - } - - if (Proto_AddToContact(hContact, m_szModuleName) != 0) { - // For some reason we failed to register the protocol to this contact - db_delete_contact(hContact); - debugLogA("Failed to register ICQ contact %u", dwUin); - return INVALID_CONTACT_ID; - } - - setDword(hContact, UNIQUEIDSETTING, dwUin); - - if (!bIsSyncingCL) { - db_set_b(hContact, "CList", "NotOnList", 1); - setContactHidden(hContact, 1); - - setWord(hContact, "Status", ID_STATUS_OFFLINE); - - icq_QueueUser(hContact); - - if (icqOnline()) - icq_sendNewContact(dwUin, nullptr); - } - AddToContactsCache(hContact, dwUin, nullptr); - *Added = 1; - debugLogA("ICQ contact %u created ok", dwUin); - return hContact; - } - - // not in list, check that uin do not belong to us - if (getContactUin(NULL) == dwUin) - return NULL; - - return INVALID_CONTACT_ID; -} - -MCONTACT CIcqProto::HContactFromUID(DWORD dwUin, const char *szUid, int *Added) -{ - if (dwUin) - return HContactFromUIN(dwUin, Added); - - if (Added) - *Added = 0; - - MCONTACT cc = HandleFromCacheByUid(dwUin, szUid); - if (cc) - return cc; - - for (auto &hContact : AccContacts()) { - DWORD dwContactUin; - uid_str szContactUid; - if (!getContactUid(hContact, &dwContactUin, &szContactUid)) { - if (!dwContactUin && !mir_strcmpi(szContactUid, szUid)) { - if (mir_strcmp(szContactUid, szUid)) // fix case in SN - setString(hContact, UNIQUEIDSETTING, szUid); - - return hContact; - } - } - } - - // not present: add - if (Added) { - debugLogA("Attempt to create ICQ contact by string <%s>", szUid); - - MCONTACT hContact = db_add_contact(); - Proto_AddToContact(hContact, m_szModuleName); - - setString(hContact, UNIQUEIDSETTING, szUid); - - if (!bIsSyncingCL) { - db_set_b(hContact, "CList", "NotOnList", 1); - setContactHidden(hContact, 1); - - setWord(hContact, "Status", ID_STATUS_OFFLINE); - - if (icqOnline()) - icq_sendNewContact(0, szUid); - } - AddToContactsCache(hContact, 0, szUid); - *Added = 1; - return hContact; - } - - return INVALID_CONTACT_ID; -} - -MCONTACT CIcqProto::HContactFromAuthEvent(MEVENT hEvent) -{ - DWORD body[3]; - - DBEVENTINFO dbei = {}; - dbei.cbBlob = sizeof(DWORD) * 2; - dbei.pBlob = (PBYTE)&body; - - if (db_event_get(hEvent, &dbei)) - return INVALID_CONTACT_ID; - - if (dbei.eventType != EVENTTYPE_AUTHREQUEST) - return INVALID_CONTACT_ID; - - if (mir_strcmp(dbei.szModule, m_szModuleName)) - return INVALID_CONTACT_ID; - - return DbGetAuthEventContact(&dbei); -} - -char* NickFromHandle(MCONTACT hContact) -{ - if (hContact == INVALID_CONTACT_ID) - return null_strdup(Translate("")); - - return null_strdup(_T2A(Clist_GetContactDisplayName(hContact))); -} - -char* NickFromHandleUtf(MCONTACT hContact) -{ - if (hContact == INVALID_CONTACT_ID) - return ICQTranslateUtf(LPGEN("")); - - return make_utf8_string(Clist_GetContactDisplayName(hContact)); -} - -char* strUID(DWORD dwUIN, char *pszUID) -{ - if (dwUIN && pszUID) - _ltoa(dwUIN, pszUID, 10); - - return pszUID; -} - -char* __fastcall strstrnull(const char *str, const char *substr) -{ - if (str) - return (char*)strstr(str, substr); - - return nullptr; -} - -char* __fastcall null_strdup(const char *string) -{ - if (string) - return _strdup(string); - - return nullptr; -} - - -WCHAR* __fastcall null_strdup(const WCHAR *string) -{ - if (string) - return wcsdup(string); - - return nullptr; -} - - -char* __fastcall null_strcpy(char *dest, const char *src, size_t maxlen) -{ - if (!dest) - return nullptr; - - if (src && src[0]) { - strncpy(dest, src, maxlen); - dest[maxlen] = '\0'; - } - else - dest[0] = '\0'; - - return dest; -} - - -WCHAR* __fastcall null_strcpy(WCHAR *dest, const WCHAR *src, size_t maxlen) -{ - if (!dest) - return nullptr; - - if (src && src[0]) { - wcsncpy(dest, src, maxlen); - dest[maxlen] = '\0'; - } - else - dest[0] = '\0'; - - return dest; -} - - -size_t __fastcall null_strcut(char *string, size_t maxlen) -{ // limit the string to max length (null & utf-8 strings ready) - size_t len = mir_strlen(string); - if (len < maxlen) - return len; - - len = maxlen; - - if (UTF8_IsValid(string)) // handle utf-8 string - { // find the first byte of possible multi-byte character - while ((string[len] & 0xc0) == 0x80) len--; - } - - // simply cut the string - string[len] = '\0'; - return len; -} - - -void parseServerAddress(char* szServer, WORD* wPort) -{ - int i = 0; - - while (szServer[i] && szServer[i] != ':') i++; - if (szServer[i] == ':') { // port included - *wPort = atoi(&szServer[i + 1]); - } // otherwise do not change port - - szServer[i] = '\0'; -} - -char* DemangleXml(const char *string, size_t len) -{ - char *szWork = (char*)SAFE_MALLOC(len + 1), *szChar = szWork; - - for (size_t i = 0; i < len; i++) { - if (!_strnicmp(string + i, ">", 4)) { - *szChar = '>'; - szChar++; - i += 3; - } - else if (!_strnicmp(string + i, "<", 4)) { - *szChar = '<'; - szChar++; - i += 3; - } - else if (!_strnicmp(string + i, "&", 5)) { - *szChar = '&'; - szChar++; - i += 4; - } - else if (!_strnicmp(string + i, """, 6)) { - *szChar = '"'; - szChar++; - i += 5; - } - else { - *szChar = string[i]; - szChar++; - } - } - *szChar = '\0'; - - return szWork; -} - -char* MangleXml(const char *string, size_t len) -{ - size_t l = 1; - char *szWork, *szChar; - - for (size_t i = 0; i < len; i++) { - if (string[i] == '<' || string[i] == '>') - l += 4; - else if (string[i] == '&') - l += 5; - else if (string[i] == '"') - l += 6; - else l++; - } - szChar = szWork = (char*)SAFE_MALLOC(l + 1); - for (size_t i = 0; i < len; i++) { - if (string[i] == '<') { - *(DWORD*)szChar = ';tl&'; - szChar += 4; - } - else if (string[i] == '>') { - *(DWORD*)szChar = ';tg&'; - szChar += 4; - } - else if (string[i] == '&') { - *(DWORD*)szChar = 'pma&'; - szChar += 4; - *szChar = ';'; - szChar++; - } - else if (string[i] == '"') { - *(DWORD*)szChar = 'ouq&'; - szChar += 4; - *(WORD*)szChar = ';t'; - szChar += 2; - } - else { - *szChar = string[i]; - szChar++; - } - } - *szChar = '\0'; - - return szWork; -} - -char* EliminateHtml(const char *string, size_t len) -{ - char *tmp = (char*)SAFE_MALLOC(len + 1); - BOOL tag = FALSE; - char *res; - - for (size_t i = 0, j = 0; i < len; i++) { - if (!tag && string[i] == '<') { - if ((i + 4 <= len) && (!_strnicmp(string + i, "
", 4) || !_strnicmp(string + i, "
", 5))) { // insert newline - tmp[j] = '\r'; - j++; - tmp[j] = '\n'; - j++; - } - tag = TRUE; - } - else if (tag && string[i] == '>') { - tag = FALSE; - } - else if (!tag) { - tmp[j] = string[i]; - j++; - } - tmp[j] = '\0'; - } - SAFE_FREE((void**)&string); - res = DemangleXml(tmp, mir_strlen(tmp)); - SAFE_FREE((void**)&tmp); - - return res; -} - -char* ApplyEncoding(const char *string, const char *pszEncoding) -{ - // decode encoding to Utf-8 - if (string && pszEncoding) { // we do only encodings known to icq5.1 // TODO: check if this is enough - if (!_strnicmp(pszEncoding, "utf-8", 5)) // it is utf-8 encoded - return null_strdup(string); - - if (!_strnicmp(pszEncoding, "unicode-2-0", 11)) { // it is UCS-2 encoded - size_t wLen = mir_wstrlen((WCHAR*)string) + 1; - WCHAR *szStr = (WCHAR*)_alloca(wLen * 2); - BYTE *tmp = (BYTE*)string; - - unpackWideString(&tmp, szStr, wLen * 2); - - return make_utf8_string(szStr); - } - if (!_strnicmp(pszEncoding, "iso-8859-1", 10)) // we use "Latin I" instead - it does the job - return ansi_to_utf8_codepage(string, 1252); - } - if (string) // consider it CP_ACP - return ansi_to_utf8(string); - - return nullptr; -} - -void CIcqProto::ResetSettingsOnListReload() -{ - // Reset a bunch of session specific settings - setWord(DBSETTING_SERVLIST_PRIVACY, 0); - setWord(DBSETTING_SERVLIST_METAINFO, 0); - setWord(DBSETTING_SERVLIST_AVATAR, 0); - setWord(DBSETTING_SERVLIST_PHOTO, 0); - setWord("SrvRecordCount", 0); - delSetting(DBSETTING_SERVLIST_UNHANDLED); - - for (auto &hContact : AccContacts()) { - // All these values will be restored during the serv-list receive - setWord(hContact, DBSETTING_SERVLIST_ID, 0); - setWord(hContact, DBSETTING_SERVLIST_GROUP, 0); - setWord(hContact, DBSETTING_SERVLIST_PERMIT, 0); - setWord(hContact, DBSETTING_SERVLIST_DENY, 0); - delSetting(hContact, DBSETTING_SERVLIST_IGNORE); - setByte(hContact, "Auth", 0); - delSetting(hContact, DBSETTING_SERVLIST_DATA); - } - - FlushSrvGroupsCache(); -} - -void CIcqProto::ResetSettingsOnConnect() -{ - // Reset a bunch of session specific settings - setByte("SrvVisibility", 0); - setDword("IdleTS", 0); - - for (auto &hContact : AccContacts()) { - setDword(hContact, "LogonTS", 0); - setDword(hContact, "IdleTS", 0); - setDword(hContact, "TickTS", 0); - setByte(hContact, "TemporaryVisible", 0); - - // All these values will be restored during the login - if (getContactStatus(hContact) != ID_STATUS_OFFLINE) - setWord(hContact, "Status", ID_STATUS_OFFLINE); - } -} - -void CIcqProto::ResetSettingsOnLoad() -{ - setDword("IdleTS", 0); - setDword("LogonTS", 0); - - for (auto &hContact : AccContacts()) { - setDword(hContact, "LogonTS", 0); - setDword(hContact, "IdleTS", 0); - setDword(hContact, "TickTS", 0); - if (getContactStatus(hContact) != ID_STATUS_OFFLINE) { - setWord(hContact, "Status", ID_STATUS_OFFLINE); - - delSetting(hContact, DBSETTING_XSTATUS_ID); - delSetting(hContact, DBSETTING_XSTATUS_NAME); - delSetting(hContact, DBSETTING_XSTATUS_MSG); - } - setByte(hContact, "DCStatus", 0); - } -} - -int RandRange(int nLow, int nHigh) -{ - return nLow + (int)((nHigh - nLow + 1)*rand() / (RAND_MAX + 1.0)); -} - - -bool IsStringUIN(const char *pszString) -{ - size_t nLen = mir_strlen(pszString); - - if (nLen > 0 && pszString[0] != '0') { - for (size_t i = 0; i < nLen; i++) - if ((pszString[i] < '0') || (pszString[i] > '9')) - return FALSE; - - return TRUE; - } - - return FALSE; -} - - -void __cdecl CIcqProto::ProtocolAckThread(icq_ack_args* pArguments) -{ - Thread_SetName("ICQ: ProtocolAckThread"); - Sleep(150); - - if (pArguments->nAckResult == ACKRESULT_SUCCESS) - debugLogA("Sent fake message ack"); - else if (pArguments->nAckResult == ACKRESULT_FAILED) - debugLogA("Message delivery failed"); - - ProtoBroadcastAck(pArguments->hContact, pArguments->nAckType, pArguments->nAckResult, pArguments->hSequence, pArguments->pszMessage); - - SAFE_FREE((void**)(char **)&pArguments->pszMessage); - SAFE_FREE((void**)&pArguments); -} - -void CIcqProto::SendProtoAck(MCONTACT hContact, DWORD dwCookie, int nAckResult, int nAckType, char* pszMessage) -{ - icq_ack_args* pArgs = (icq_ack_args*)SAFE_MALLOC(sizeof(icq_ack_args)); // This will be freed in the new thread - pArgs->hContact = hContact; - pArgs->hSequence = (HANDLE)dwCookie; - pArgs->nAckResult = nAckResult; - pArgs->nAckType = nAckType; - pArgs->pszMessage = (LPARAM)null_strdup(pszMessage); - - ForkThread((MyThreadFunc)&CIcqProto::ProtocolAckThread, pArgs); -} - -void CIcqProto::SetCurrentStatus(int nStatus) -{ - int nOldStatus = m_iStatus; - - m_iStatus = nStatus; - ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)nOldStatus, nStatus); -} - - -int CIcqProto::IsMetaInfoChanged(MCONTACT hContact) -{ - DBVARIANT infoToken = { DBVT_DELETED }; - int res = 0; - - if (!getSetting(hContact, DBSETTING_METAINFO_TOKEN, &infoToken)) { // contact does have info from directory, check if it is not outdated - double dInfoTime = 0; - double dInfoSaved = 0; - - if ((dInfoTime = getSettingDouble(hContact, DBSETTING_METAINFO_TIME, 0)) > 0) { - if ((dInfoSaved = getSettingDouble(hContact, DBSETTING_METAINFO_SAVED, 0)) > 0) { - if (dInfoSaved < dInfoTime) - res = 2; // directory info outdated - } - else - res = 1; // directory info not saved at all - } - - db_free(&infoToken); - } - else { // it cannot be detected if user info was not changed, so use a generic threshold - DBVARIANT infoSaved = { DBVT_DELETED }; - DWORD dwInfoTime = 0; - - if (!getSetting(hContact, DBSETTING_METAINFO_SAVED, &infoSaved)) { - if (infoSaved.type == DBVT_BLOB && infoSaved.cpbVal == 8) { - double dwTime = *(double*)infoSaved.pbVal; - - dwInfoTime = (dwTime - 25567) * 86400; - } - else if (infoSaved.type == DBVT_DWORD) - dwInfoTime = infoSaved.dVal; - - db_free(&infoSaved); - - if ((time(0) - dwInfoTime) > 14 * 3600 * 24) { - res = 3; // threshold exceeded - } - } - else res = 4; // no timestamp found - } - - return res; -} - - -void __cdecl CIcqProto::SetStatusNoteThread(void *pDelay) -{ - Thread_SetName("ICQ: SetStatusNoteThread"); - if (pDelay) - SleepEx((UINT_PTR)pDelay, TRUE); - - mir_cslockfull l(cookieMutex); - - if (icqOnline() && (setStatusNoteText || setStatusMoodData)) { // send status note change packets, write status note to database - if (setStatusNoteText) { // change status note in directory - mir_cslockfull rlck(m_ratesMutex); - if (m_rates) { // rate management - WORD wGroup = m_rates->getGroupFromSNAC(ICQ_EXTENSIONS_FAMILY, ICQ_META_CLI_REQUEST); - - while (m_rates->getNextRateLevel(wGroup) < m_rates->getLimitLevel(wGroup, RML_LIMIT)) { // we are over rate, need to wait before sending - int nDelay = m_rates->getDelayToLimitLevel(wGroup, RML_IDLE_10); - - rlck.unlock(); - l.unlock(); - - debugLogA("Rates: SetStatusNote delayed %dms", nDelay); - - SleepEx(nDelay, TRUE); // do not keep things locked during sleep - l.lock(); - rlck.lock(); - if (!m_rates) // we lost connection when we slept, go away - break; - } - } - rlck.unlock(); - - BYTE *pBuffer = nullptr; - size_t cbBuffer = 0; - - ppackTLV(&pBuffer, &cbBuffer, 0x226, mir_strlen(setStatusNoteText), (BYTE*)setStatusNoteText); - icq_changeUserDirectoryInfoServ(pBuffer, cbBuffer, DIRECTORYREQUEST_UPDATENOTE); - - SAFE_FREE((void**)&pBuffer); - } - - if (setStatusNoteText || setStatusMoodData) { // change status note and mood in session data - mir_cslockfull rlck(m_ratesMutex); - if (m_rates) { // rate management - WORD wGroup = m_rates->getGroupFromSNAC(ICQ_SERVICE_FAMILY, ICQ_CLIENT_SET_STATUS); - - while (m_rates->getNextRateLevel(wGroup) < m_rates->getLimitLevel(wGroup, RML_LIMIT)) { // we are over rate, need to wait before sending - int nDelay = m_rates->getDelayToLimitLevel(wGroup, RML_IDLE_10); - - rlck.unlock(); - l.unlock(); - - debugLogA("Rates: SetStatusNote delayed %dms", nDelay); - - SleepEx(nDelay, TRUE); // do not keep things locked during sleep - l.lock(); - rlck.lock(); - if (!m_rates) // we lost connection when we slept, go away - break; - } - } - rlck.unlock(); - - // check if the session data were not updated already - char *szCurrentStatusNote = getSettingStringUtf(NULL, DBSETTING_STATUS_NOTE, nullptr); - char *szCurrentStatusMood = nullptr; - DBVARIANT dbv = { DBVT_DELETED }; - - if (m_bMoodsEnabled && !getString(DBSETTING_STATUS_MOOD, &dbv)) - szCurrentStatusMood = dbv.pszVal; - - if (!setStatusNoteText && szCurrentStatusNote) - setStatusNoteText = null_strdup(szCurrentStatusNote); - if (m_bMoodsEnabled && !setStatusMoodData && szCurrentStatusMood) - setStatusMoodData = null_strdup(szCurrentStatusMood); - - if (mir_strcmp(szCurrentStatusNote, setStatusNoteText) || (m_bMoodsEnabled && mir_strcmp(szCurrentStatusMood, setStatusMoodData))) { - db_set_utf(NULL, m_szModuleName, DBSETTING_STATUS_NOTE, setStatusNoteText); - if (m_bMoodsEnabled) - setString(DBSETTING_STATUS_MOOD, setStatusMoodData); - - size_t wStatusNoteLen = mir_strlen(setStatusNoteText); - size_t wStatusMoodLen = m_bMoodsEnabled ? mir_strlen(setStatusMoodData) : 0; - size_t wDataLen = (wStatusNoteLen ? wStatusNoteLen + 4 : 0) + 4 + wStatusMoodLen + 4; - - icq_packet packet; - serverPacketInit(&packet, wDataLen + 14); - packFNACHeader(&packet, ICQ_SERVICE_FAMILY, ICQ_CLIENT_SET_STATUS); - // Change only session data - packWord(&packet, 0x1D); // TLV 1D - packWord(&packet, WORD(wDataLen)); // TLV length - packWord(&packet, 0x02); // Item Type - if (wStatusNoteLen) { - packWord(&packet, 0x400 | WORD(wStatusNoteLen + 4)); // Flags + Item Length - packWord(&packet, WORD(wStatusNoteLen)); // Text Length - packBuffer(&packet, (LPBYTE)setStatusNoteText, wStatusNoteLen); - packWord(&packet, 0); // Encoding not specified (utf-8 is default) - } - else packWord(&packet, 0); // Flags + Item Length - - packWord(&packet, 0x0E); // Item Type - packWord(&packet, WORD(wStatusMoodLen)); // Flags + Item Length - if (wStatusMoodLen) - packBuffer(&packet, (LPBYTE)setStatusMoodData, wStatusMoodLen); // Mood - - sendServPacket(&packet); - } - SAFE_FREE(&szCurrentStatusNote); - db_free(&dbv); - } - } - SAFE_FREE(&setStatusNoteText); - SAFE_FREE(&setStatusMoodData); -} - - -int CIcqProto::SetStatusNote(const char *szStatusNote, DWORD dwDelay, int bForce) -{ - int bChanged = FALSE; - - // bForce is intended for login sequence - need to call this earlier than icqOnline() - // the process is delayed and icqOnline() is ready when needed inside SetStatusNoteThread() - if (!bForce && !icqOnline()) return bChanged; - - // reuse generic critical section (used for cookies list and object variables locks) - mir_cslock l(cookieMutex); - - if (!setStatusNoteText && (!m_bMoodsEnabled || !setStatusMoodData)) { // check if the status note was changed and if yes, create thread to change it - char *szCurrentStatusNote = getSettingStringUtf(NULL, DBSETTING_STATUS_NOTE, nullptr); - - if (mir_strcmp(szCurrentStatusNote, szStatusNote)) { // status note was changed - // create thread to change status note on existing server connection - setStatusNoteText = null_strdup(szStatusNote); - - if (dwDelay) - ForkThread(&CIcqProto::SetStatusNoteThread, (void*)dwDelay); - else // we cannot afford any delay, so do not run in separate thread - SetStatusNoteThread(nullptr); - - bChanged = TRUE; - } - SAFE_FREE(&szCurrentStatusNote); - } - else { // only alter status note object with new status note, keep the thread waiting for execution - SAFE_FREE(&setStatusNoteText); - setStatusNoteText = null_strdup(szStatusNote); - - bChanged = TRUE; - } - - return bChanged; -} - - -int CIcqProto::SetStatusMood(const char *szMoodData, DWORD dwDelay) -{ - int bChanged = FALSE; - - if (!icqOnline()) return bChanged; - - // reuse generic critical section (used for cookies list and object variables locks) - mir_cslock l(cookieMutex); - - if (!setStatusNoteText && !setStatusMoodData) { // check if the status mood was changed and if yes, create thread to change it - char *szCurrentStatusMood = nullptr; - DBVARIANT dbv = { DBVT_DELETED }; - - if (!getString(DBSETTING_STATUS_MOOD, &dbv)) - szCurrentStatusMood = dbv.pszVal; - - if (mir_strcmp(szCurrentStatusMood, szMoodData)) { // status mood was changed - // create thread to change status mood on existing server connection - setStatusMoodData = null_strdup(szMoodData); - if (dwDelay) - ForkThread(&CIcqProto::SetStatusNoteThread, (void*)dwDelay); - else // we cannot afford any delay, so do not run in separate thread - SetStatusNoteThread(nullptr); - - bChanged = TRUE; - } - db_free(&dbv); - } - else { // only alter status mood object with new status mood, keep the thread waiting for execution - SAFE_FREE(&setStatusMoodData); - setStatusMoodData = null_strdup(szMoodData); - - bChanged = TRUE; - } - - return bChanged; -} - - -void CIcqProto::writeDbInfoSettingTLVStringUtf(MCONTACT hContact, const char *szSetting, oscar_tlv_chain *chain, WORD wTlv) -{ - oscar_tlv *pTLV = chain->getTLV(wTlv, 1); - - if (pTLV && pTLV->wLen > 0) { - char *str = (char*)_alloca(pTLV->wLen + 1); - - memcpy(str, pTLV->pData, pTLV->wLen); - str[pTLV->wLen] = '\0'; - db_set_utf(hContact, m_szModuleName, szSetting, str); - } - else delSetting(hContact, szSetting); -} - - -void CIcqProto::writeDbInfoSettingTLVWord(MCONTACT hContact, const char *szSetting, oscar_tlv_chain *chain, WORD wTlv) -{ - int num = chain->getNumber(wTlv, 1); - if (num > 0 && num != 0x7FFF) - setWord(hContact, szSetting, num); - else - delSetting(hContact, szSetting); -} - - -void CIcqProto::writeDbInfoSettingTLVByte(MCONTACT hContact, const char *szSetting, oscar_tlv_chain *chain, WORD wTlv) -{ - int num = chain->getNumber(wTlv, 1); - if (num > 0 && num != 0x7F) - setByte(hContact, szSetting, num); - else - delSetting(hContact, szSetting); -} - - -void CIcqProto::writeDbInfoSettingTLVDouble(MCONTACT hContact, const char *szSetting, oscar_tlv_chain *chain, WORD wTlv) -{ - double num = chain->getDouble(wTlv, 1); - if (num > 0) - setSettingDouble(hContact, szSetting, num); - else - delSetting(hContact, szSetting); -} - -void CIcqProto::writeDbInfoSettingTLVDate(MCONTACT hContact, const char* szSettingYear, const char* szSettingMonth, const char* szSettingDay, oscar_tlv_chain* chain, WORD wTlv) -{ - double time = chain->getDouble(wTlv, 1); - - if (time > 0) { // date is stored as double with unit equal to a day, incrementing since 1/1/1900 0:00 GMT - SYSTEMTIME sTime = { 0 }; - if (VariantTimeToSystemTime(time + 2, &sTime)) { - setWord(hContact, szSettingYear, sTime.wYear); - setByte(hContact, szSettingMonth, (BYTE)sTime.wMonth); - setByte(hContact, szSettingDay, (BYTE)sTime.wDay); - } - else { - delSetting(hContact, szSettingYear); - delSetting(hContact, szSettingMonth); - delSetting(hContact, szSettingDay); - } - } - else { - delSetting(hContact, szSettingYear); - delSetting(hContact, szSettingMonth); - delSetting(hContact, szSettingDay); - } -} - - -void CIcqProto::writeDbInfoSettingTLVBlob(MCONTACT hContact, const char *szSetting, oscar_tlv_chain *chain, WORD wTlv) -{ - oscar_tlv *pTLV = chain->getTLV(wTlv, 1); - - if (pTLV && pTLV->wLen > 0) - setSettingBlob(hContact, szSetting, pTLV->pData, pTLV->wLen); - else - delSetting(hContact, szSetting); -} - -char* time2text(time_t time) -{ - tm *local = localtime(&time); - - if (local) { - char *str = asctime(local); - str[24] = '\0'; // remove new line - return str; - } - - return ""; -} - - -bool CIcqProto::validateStatusMessageRequest(MCONTACT hContact, WORD byMessageType) -{ - // Privacy control - if (getByte("StatusMsgReplyCList", 0)) { - // Don't send statusmessage to unknown contacts - if (hContact == INVALID_CONTACT_ID) - return false; - - // Don't send statusmessage to temporary contacts or hidden contacts - if (db_get_b(hContact, "CList", "NotOnList", 0) || - db_get_b(hContact, "CList", "Hidden", 0)) - return false; - - // Don't send statusmessage to invisible contacts - if (getByte("StatusMsgReplyVisible", 0)) { - WORD wStatus = getContactStatus(hContact); - if (wStatus == ID_STATUS_OFFLINE) - return false; - } - } - - // Dont send messages to people you are hiding from - if (hContact != INVALID_CONTACT_ID && - getWord(hContact, "ApparentMode", 0) == ID_STATUS_OFFLINE) { - return false; - } - - // Dont respond to request for other statuses than your current one - if ((byMessageType == MTYPE_AUTOONLINE && m_iStatus != ID_STATUS_ONLINE) || - (byMessageType == MTYPE_AUTOAWAY && m_iStatus != ID_STATUS_AWAY) || - (byMessageType == MTYPE_AUTOBUSY && m_iStatus != ID_STATUS_OCCUPIED) || - (byMessageType == MTYPE_AUTONA && m_iStatus != ID_STATUS_NA) || - (byMessageType == MTYPE_AUTODND && m_iStatus != ID_STATUS_DND) || - (byMessageType == MTYPE_AUTOFFC && m_iStatus != ID_STATUS_FREECHAT)) { - return false; - } - - if (hContact != INVALID_CONTACT_ID && m_iStatus == ID_STATUS_INVISIBLE && - getWord(hContact, "ApparentMode", 0) != ID_STATUS_ONLINE) { - if (!getByte(hContact, "TemporaryVisible", 0)) { // Allow request to temporary visible contacts - return false; - } - } - - // All OK! - return true; -} - -void __fastcall SAFE_FREE(void** p) -{ - if (*p) { - free(*p); - *p = nullptr; - } -} - -void* __fastcall SAFE_MALLOC(size_t size) -{ - void* p = nullptr; - - if (size) { - p = malloc(size); - if (p) - memset(p, 0, size); - } - return p; -} - -void* __fastcall SAFE_REALLOC(void* p, size_t size) -{ - if (p) - return realloc(p, size); - - return SAFE_MALLOC(size); -} - -DWORD ICQWaitForSingleObject(HANDLE hObject, DWORD dwMilliseconds, int bWaitAlways) -{ - DWORD dwResult; - - // will get WAIT_IO_COMPLETION for QueueUserAPC(), ignore it unless terminating - do { - dwResult = WaitForSingleObjectEx(hObject, dwMilliseconds, TRUE); - } - while (dwResult == WAIT_IO_COMPLETION && (bWaitAlways || !Miranda_IsTerminated())); - - return dwResult; -} - - -HNETLIBCONN NetLib_OpenConnection(HNETLIBUSER hUser, const char* szIdent, NETLIBOPENCONNECTION* nloc) -{ - Netlib_Logf(hUser, "%sConnecting to %s:%u", szIdent ? szIdent : "", nloc->szHost, nloc->wPort); - - nloc->cbSize = sizeof(NETLIBOPENCONNECTION); - nloc->flags |= NLOCF_V2; - return Netlib_OpenConnection(hUser, nloc); -} - - -HNETLIBBIND CIcqProto::NetLib_BindPort(NETLIBNEWCONNECTIONPROC_V2 pFunc, void* lParam, WORD* pwPort, DWORD* pdwIntIP) -{ - NETLIBBIND nlb = {}; - nlb.pfnNewConnectionV2 = pFunc; - nlb.pExtra = lParam; - SetLastError(ERROR_INVALID_PARAMETER); // this must be here - NetLib does not set any error :(( - - HNETLIBBIND hBoundPort = Netlib_BindPort(m_hDirectNetlibUser, &nlb); - - if (pwPort) *pwPort = nlb.wPort; - if (pdwIntIP) *pdwIntIP = nlb.dwInternalIP; - - return hBoundPort; -} - - -void NetLib_CloseConnection(HNETLIBCONN *hConnection, int bServerConn) -{ - if (*hConnection) { - Netlib_CloseHandle(*hConnection); - *hConnection = nullptr; - - if (bServerConn) - FreeGatewayIndex(*hConnection); - } -} - - -void NetLib_SafeCloseHandle(HANDLE *hConnection) -{ - if (*hConnection) { - Netlib_CloseHandle(*hConnection); - *hConnection = nullptr; - } -} - - -int CIcqProto::NetLog_Direct(const char *fmt, ...) -{ - char szText[1024]; - - va_list va; - va_start(va, fmt); - mir_vsnprintf(szText, sizeof(szText), fmt, va); - va_end(va); - return Netlib_Log(m_hDirectNetlibUser, szText); -} - -int CIcqProto::NetLog_Uni(BOOL bDC, const char *fmt, ...) -{ - char szText[1024]; - va_list va; - va_start(va, fmt); - mir_vsnprintf(szText, sizeof(szText), fmt, va); - va_end(va); - - HNETLIBUSER hNetlib = (bDC) ? m_hDirectNetlibUser : m_hNetlibUser; - return Netlib_Log(hNetlib, szText); -} - -char* __fastcall ICQTranslateUtf(const char *src) -{ // this takes UTF-8 strings only!!! - char *szRes = nullptr; - - if (!mir_strlen(src)) { // for the case of empty strings - return null_strdup(src); - } - - { // we can use unicode translate (0.5+) - WCHAR* usrc = make_unicode_string(src); - - szRes = make_utf8_string(TranslateW(usrc)); - - SAFE_FREE((void**)&usrc); - } - return szRes; -} - -char* __fastcall ICQTranslateUtfStatic(const char *src, char *buf, size_t bufsize) -{ // this takes UTF-8 strings only!!! - if (mir_strlen(src)) { // we can use unicode translate (0.5+) - WCHAR *usrc = make_unicode_string(src); - - make_utf8_string_static(TranslateW(usrc), buf, bufsize); - - SAFE_FREE((void**)&usrc); - } - else - buf[0] = '\0'; - - return buf; -} - -template -char* CIcqProto::GetUserStoredPassword(char(&szBuffer)[cbSize]) -{ - if (!getSettingStringStatic(NULL, "Password", szBuffer, cbSize)) - if (mir_strlen(szBuffer)) - return szBuffer; - - return nullptr; -} - - -char* CIcqProto::GetUserPassword(BOOL bAlways) -{ - if (m_szPassword[0] != '\0' && (m_bRememberPwd || bAlways)) - return m_szPassword; - - if (GetUserStoredPassword(m_szPassword)) { - m_bRememberPwd = true; - return m_szPassword; - } - - return nullptr; -} - - -WORD CIcqProto::GetMyStatusFlags() -{ - WORD wFlags = 0; - - // Webaware setting bit flag - if (getByte("WebAware", 0)) - wFlags |= STATUS_WEBAWARE; - - // DC setting bit flag - switch (getByte("DCType", 0)) { - case 0: - break; - - case 1: - wFlags |= STATUS_DCCONT; - break; - - case 2: - wFlags |= STATUS_DCAUTH; - break; - - default: - wFlags |= STATUS_DCDISABLED; - break; - } - return wFlags; -} - - -int IsValidRelativePath(const char *filename) -{ - if (strstrnull(filename, "..\\") || strstrnull(filename, "../") || - strstrnull(filename, ":\\") || strstrnull(filename, ":/") || - filename[0] == '\\' || filename[0] == '/') - return 0; // Contains malicious chars, Failure - - return 1; // Success -} - - -const char* ExtractFileName(const char *fullname) -{ - const char *szFileName; - - // already is only filename - if (((szFileName = strrchr(fullname, '\\')) == nullptr) && ((szFileName = strrchr(fullname, '/')) == nullptr)) - return fullname; - - return szFileName + 1; // skip backslash -} - - -char* FileNameToUtf(const wchar_t *filename) -{ - WCHAR *usFileName = nullptr; - int wchars = GetLongPathName(filename, usFileName, 0); - usFileName = (WCHAR*)_alloca((wchars + 1) * sizeof(WCHAR)); - GetLongPathName(filename, usFileName, wchars); - - return make_utf8_string(usFileName); -} - - -int FileAccessUtf(const char *path, int mode) -{ - size_t size = mir_strlen(path) + 2; - wchar_t *szPath = (wchar_t*)_alloca(size * sizeof(wchar_t)); - - if (make_unicode_string_static(path, szPath, size)) - return _waccess(szPath, mode); - - return -1; -} - - -int FileStatUtf(const char *path, struct _stati64 *buffer) -{ - size_t size = mir_strlen(path) + 2; - wchar_t *szPath = (wchar_t*)_alloca(size * sizeof(wchar_t)); - - if (make_unicode_string_static(path, szPath, size)) - return _wstat64(szPath, buffer); - - return -1; -} - - -int MakeDirUtf(const char *dir) -{ - int wRes = -1; - size_t size = mir_strlen(dir) + 2; - wchar_t *szDir = (wchar_t*)_alloca(size * sizeof(wchar_t)); - - if (make_unicode_string_static(dir, szDir, size)) { // _wmkdir can created only one dir at once - wRes = _wmkdir(szDir); - // check if dir not already existed - return success if yes - if (wRes == -1 && errno == 17 /* EEXIST */) - wRes = 0; - else if (wRes && errno == 2 /* ENOENT */) { // failed, try one directory less first - char *szLast = (char*)strrchr(dir, '\\'); - if (!szLast) szLast = (char*)strrchr(dir, '/'); - if (szLast) { - char cOld = *szLast; - - *szLast = '\0'; - if (!MakeDirUtf(dir)) - wRes = _wmkdir(szDir); - - *szLast = cOld; - } - } - } - - return wRes; -} - - -int OpenFileUtf(const char *filename, int oflag, int pmode) -{ - size_t size = mir_strlen(filename) + 2; - wchar_t *szFile = (wchar_t*)_alloca(size * sizeof(wchar_t)); - - if (make_unicode_string_static(filename, szFile, size)) - return _wopen(szFile, oflag, pmode); - - return -1; -} - - -WCHAR *GetWindowTextUcs(HWND hWnd) -{ - int nLen = GetWindowTextLengthW(hWnd); - WCHAR *utext = (WCHAR*)SAFE_MALLOC((nLen + 2) * sizeof(WCHAR)); - GetWindowTextW(hWnd, utext, nLen + 1); - return utext; -} - - -void SetWindowTextUcs(HWND hWnd, WCHAR *text) -{ - SetWindowTextW(hWnd, text); -} - - -char* GetWindowTextUtf(HWND hWnd) -{ - int nLen = GetWindowTextLength(hWnd); - wchar_t *szText = (wchar_t*)_alloca((nLen + 2) * sizeof(wchar_t)); - - GetWindowText(hWnd, szText, nLen + 1); - - return make_utf8_string(szText); -} - - -char* GetDlgItemTextUtf(HWND hwndDlg, int iItem) -{ - return GetWindowTextUtf(GetDlgItem(hwndDlg, iItem)); -} - - -void SetWindowTextUtf(HWND hWnd, const char *szText) -{ - size_t size = mir_strlen(szText) + 2; - wchar_t *tszText = (wchar_t*)_alloca(size * sizeof(wchar_t)); - - if (make_unicode_string_static(szText, tszText, size)) - SetWindowText(hWnd, tszText); -} - - -void SetDlgItemTextUtf(HWND hwndDlg, int iItem, const char *szText) -{ - SetWindowTextUtf(GetDlgItem(hwndDlg, iItem), szText); -} - - -static int ControlAddStringUtf(HWND ctrl, DWORD msg, const char *szString) -{ - char str[MAX_PATH]; - char *szItem = ICQTranslateUtfStatic(szString, str, MAX_PATH); - int item = -1; - WCHAR *wItem = make_unicode_string(szItem); - item = SendMessage(ctrl, msg, 0, (LPARAM)wItem); - SAFE_FREE((void**)&wItem); - return item; -} - -int ComboBoxAddStringUtf(HWND hCombo, const char *szString, DWORD data) -{ - int item = ControlAddStringUtf(hCombo, CB_ADDSTRING, szString); - SendMessage(hCombo, CB_SETITEMDATA, item, data); - - return item; -} - -int ListBoxAddStringUtf(HWND hList, const char *szString) -{ - return ControlAddStringUtf(hList, LB_ADDSTRING, szString); -} - -int MessageBoxUtf(HWND hWnd, const char *szText, const char *szCaption, UINT uType) -{ - int res; - char str[1024]; - char cap[MAX_PATH]; - WCHAR *text = make_unicode_string(ICQTranslateUtfStatic(szText, str, 1024)); - WCHAR *caption = make_unicode_string(ICQTranslateUtfStatic(szCaption, cap, MAX_PATH)); - res = MessageBoxW(hWnd, text, caption, uType); - SAFE_FREE((void**)&caption); - SAFE_FREE((void**)&text); - return res; -} - -char* CIcqProto::ConvertMsgToUserSpecificAnsi(MCONTACT hContact, const char* szMsg) -{ // this takes utf-8 encoded message - WORD wCP = getWord(hContact, "CodePage", m_wAnsiCodepage); - char* szAnsi = nullptr; - - if (wCP != CP_ACP) // convert to proper codepage - if (!utf8_decode_codepage(szMsg, &szAnsi, wCP)) - return nullptr; - - return szAnsi; -} - -// just broadcast generic send error with dummy cookie and return that cookie -DWORD CIcqProto::ReportGenericSendError(MCONTACT hContact, int nType, const char* szErrorMsg) -{ - DWORD dwCookie = GenerateCookie(0); - SendProtoAck(hContact, dwCookie, ACKRESULT_FAILED, nType, Translate(szErrorMsg)); - return dwCookie; -} diff --git a/protocols/IcqOscarJ/src/utilities.h b/protocols/IcqOscarJ/src/utilities.h deleted file mode 100644 index 2146d99a62..0000000000 --- a/protocols/IcqOscarJ/src/utilities.h +++ /dev/null @@ -1,135 +0,0 @@ -// ---------------------------------------------------------------------------80 -// ICQ plugin for Miranda Instant Messenger -// ________________________________________ -// -// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede -// Copyright © 2001-2002 Jon Keating, Richard Hughes -// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater -// Copyright © 2004-2010 Joe Kucera -// Copyright © 2012-2018 Miranda NG team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// ----------------------------------------------------------------------------- - -#ifndef __UTILITIES_H -#define __UTILITIES_H - -struct icq_ack_args -{ - MCONTACT hContact; - int nAckType; - int nAckResult; - HANDLE hSequence; - LPARAM pszMessage; -}; - -struct icq_contacts_cache -{ - MCONTACT hContact; - DWORD dwUin; - const char *szUid; -}; - - -/*---------* Functions *---------------*/ - -void MoveDlgItem(HWND hwndDlg, int iItem, int left, int top, int width, int height); -void EnableDlgItem(HWND hwndDlg, UINT control, int state); -void ShowDlgItem(HWND hwndDlg, UINT control, int state); -void icq_EnableMultipleControls(HWND hwndDlg, const UINT* controls, int cControls, int state); -void icq_ShowMultipleControls(HWND hwndDlg, const UINT* controls, int cControls, int state); -int IcqStatusToMiranda(WORD wStatus); -WORD MirandaStatusToIcq(int nStatus); -int MirandaStatusToSupported(int nMirandaStatus); -char* MirandaStatusToStringUtf(int); - -int AwayMsgTypeToStatus(int nMsgType); - -void SetGatewayIndex(HANDLE hConn, DWORD dwIndex); -DWORD GetGatewayIndex(HANDLE hConn); -void FreeGatewayIndex(HANDLE hConn); - -char* NickFromHandle(MCONTACT hContact); -char* NickFromHandleUtf(MCONTACT hContact); -char* strUID(DWORD dwUIN, char *pszUID); - -char* __fastcall strstrnull(const char *str, const char *substr); -char* __fastcall null_strdup(const char *string); -char* __fastcall null_strcpy(char *dest, const char *src, size_t maxlen); -size_t __fastcall null_strcut(char *string, size_t maxlen); - -WCHAR* __fastcall null_strdup(const WCHAR *string); -WCHAR* __fastcall null_strcpy(WCHAR *dest, const WCHAR *src, size_t maxlen); - -void parseServerAddress(char *szServer, WORD* wPort); - -char* DemangleXml(const char *string, size_t len); -char* MangleXml(const char *string, size_t len); -char* EliminateHtml(const char *string, size_t len); -char* ApplyEncoding(const char *string, const char *pszEncoding); - -int RandRange(int nLow, int nHigh); - -bool IsStringUIN(const char *pszString); - -char* time2text(time_t time); - -void __fastcall SAFE_FREE(void** p); -void* __fastcall SAFE_MALLOC(size_t size); -void* __fastcall SAFE_REALLOC(void* p, size_t size); - -__inline static void SAFE_FREE(char** str) { SAFE_FREE((void**)str); } -__inline static void SAFE_FREE(WCHAR** str) { SAFE_FREE((void**)str); } - -DWORD ICQWaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds, int bWaitAlways = FALSE); - -HNETLIBCONN NetLib_OpenConnection(HNETLIBUSER hUser, const char* szIdent, NETLIBOPENCONNECTION* nloc); -void NetLib_CloseConnection(HNETLIBCONN *hConnection, int bServerConn); -void NetLib_SafeCloseHandle(HANDLE *); - -char* __fastcall ICQTranslateUtf(const char *src); -char* __fastcall ICQTranslateUtfStatic(const char *src, char *buf, size_t bufsize); - -WORD GetMyStatusFlags(); - -/* Unicode FS utility functions */ - -int IsValidRelativePath(const char *filename); -LPCSTR ExtractFileName(const char *fullname); -char* FileNameToUtf(const wchar_t *filename); - -int FileAccessUtf(const char *path, int mode); -int FileStatUtf(const char *path, struct _stati64 *buffer); -int MakeDirUtf(const char *dir); -int OpenFileUtf(const char *filename, int oflag, int pmode); - -/* Unicode UI utility functions */ -WCHAR* GetWindowTextUcs(HWND hWnd); -void SetWindowTextUcs(HWND hWnd, WCHAR *text); -char* GetWindowTextUtf(HWND hWnd); -char* GetDlgItemTextUtf(HWND hwndDlg, int iItem); -void SetWindowTextUtf(HWND hWnd, const char *szText); -void SetDlgItemTextUtf(HWND hwndDlg, int iItem, const char *szText); - -int ComboBoxAddStringUtf(HWND hCombo, const char *szString, DWORD data); -int ListBoxAddStringUtf(HWND hList, const char *szString); - -int MessageBoxUtf(HWND hWnd, const char *szText, const char *szCaption, UINT uType); - -void InitXStatusIcons(); -void setContactExtraIcon(MCONTACT hContact, int xstatus); -int OnReloadIcons(WPARAM wParam, LPARAM lParam); - -#endif /* __UTILITIES_H */ diff --git a/protocols/IcqOscarJ/src/version.h b/protocols/IcqOscarJ/src/version.h deleted file mode 100644 index 253becb75d..0000000000 --- a/protocols/IcqOscarJ/src/version.h +++ /dev/null @@ -1,13 +0,0 @@ -#define __MAJOR_VERSION 0 -#define __MINOR_VERSION 95 -#define __RELEASE_NUM 8 -#define __BUILD_NUM 1 - -#include - -#define __PLUGIN_NAME "IcqOscarJ protocol" -#define __FILENAME "ICQ.dll" -#define __DESCRIPTION "ICQ protocol support for Miranda NG." -#define __AUTHOR "Joe Kucera, Bio, Martin Öberg, Richard Hughes, Jon Keating, etc." -#define __AUTHORWEB "https://miranda-ng.org/p/ICQ/" -#define __COPYRIGHT "© 2000-18 M.Öberg, R.Hughes, J.Keating, Bio, Angeli-Ka, G.Hazan, J.Kucera" -- cgit v1.2.3